bvaughn / react-window

React components for efficiently rendering large lists and tabular data
https://react-window.now.sh/
MIT License
15.54k stars 779 forks source link

Data change cause whole list to rerender (its ok), but focus is lost. #674

Closed skelawsky closed 1 year ago

skelawsky commented 1 year ago

When data rerender due to data fetch from server inputs inside lose focus. I think this is not desired activity. How to work around it?

import {
  flexRender,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";
import React from "react";
import { FixedSizeList as List } from "react-window";

const TableModelWindow = ({ data, columns }) => {
  const table = useReactTable({
    data,
    columns,

    getCoreRowModel: getCoreRowModel(),
  });

  const { rows } = table.getRowModel();

  const Row = React.useCallback(
    ({ index, style }) => {
      const row = rows[index];
      console.log(row);
      return (
        <tr style={style} key={row.id}>
          {row.getVisibleCells().map((cell) => {
            console.log(cell.id);
            return (
              <td key={cell.id}>
                {flexRender(cell.column.columnDef.cell, cell.getContext())}
              </td>
            );
          })}
        </tr>
      );
    },
    [rows]
  );

  return (
    <>
      <div>
        <List
          height={150}
          itemCount={table.getRowModel().rows.length}
          itemSize={35}
          width={800}
        >
          {Row}
        </List>
      </div>
    </>
  );
};

export default TableModelWindow;
skelawsky commented 1 year ago

This fixes the problem.

itemData: any
Contextual data to be passed to the item renderer as a data prop. This is a light-weight alternative to React's built-in context API.

Item data is useful for item renderers that are class components.

class ComponentThatRendersAListOfItems extends PureComponent {
  render() {
    // Pass items array to the item renderer component as itemData:
    return (
      <FixedSizeList
        itemData={this.props.itemsArray}
        {...otherListProps}
      >
        {ItemRenderer}
      </FixedSizeList>
    );
  }
}

// The item renderer is declared outside of the list-rendering component.
// So it has no way to directly access the items array.
class ItemRenderer extends PureComponent {
  render() {
    // Access the items array using the "data" prop:
    const item = this.props.data[this.props.index];

    return (
      <div style={this.props.style}>
        {item.name}
      </div>
    );
  }
}