使用 react-table 7,当使用双向绑定到 table 的数据源时,editable 单元格会在每次更改时重新呈现,我失去了对输入的关注

Using react-table 7, editable cell re-renders on every change when using two-way binding to table's data source and I lose focus on the input

使用 react-table 7,我的单元格重新呈现并失去对每个更改的关注。我将其绑定到其父组件中的 属性 的两种方式。在单元格中输入会更新我用来填充 table 的数据源,因此它会重新呈现 table.

官方文档以一种相当复杂的方式绕过它:单元格接收一个传递给 table 的 updateMyData 函数,单元格定义有自己的状态,以便 onChange 更新单元格的内部状态, onBlur 运行 updateMyData 函数。该解决方案并不真正适用于我的项目结构以及我打算如何重用组件。

理想情况下,我想继续使用现有的双向绑定方法,但我没有想法。 table 数据已经被记忆,但由于它确实发生了变化,它重新呈现 table,我失去了焦点。

这是我非常简单的单元格定义:

    tempTable["defaultColumn"] = {
      Cell: ({value, row, column}) => {
                // TODO: fix this so that inputting doesn't render a new component, otherwise I lose focus on every change.
                return <input 
                    key={`Cell_${row}_${column}`} 
                    type="number" 
                    value={value} 
                    onChange={(e) => updateData(e, column, row)} />
            }
        }

我的 updateData 函数调用了 onChange:

 const updateData = useCallback(
    (event, column, row) => {
      props.onProductTableChange(event, column, row);
    }, [props]
  );

以及在我的父组件中定义的 onProductTableChange 函数

    // handles changes to the events products table
    const handleProductTableChange =  useCallback(
        (event, column, row) => {
            // get the event products in a new array
            let newEventProducts = [...eventProducts];
            // let the value be the value of the event target
            let value = event.target.value
            // if the column we're updating is name, manually format some of the data differently... 
            if (column.id === "Name") {
                value = parseInt(event.target.value);
                newEventProducts[row.index].Id = value;
                // ... and manually get the new name, since we only updated the id
                const allProducts = [...ddvProducts];
                newEventProducts[row.index].Name = allProducts.filter(prod => prod.id === value)[0]["name"];
            } else {
                // else just set the column.id ("SalePrice", "QuantityAllocated", etc) to the new value
                newEventProducts[row.index][column.id] = value;
            }
            setEventProducts(newEventProducts);
            console.log(newEventProducts);
        }, 
        [setEventProducts, ddvProducts, eventProducts]
    );

提前致谢,我很想知道我正在尝试做的事情是否可行。

我最终无法解决这个问题,不得不像示例中那样管理每个单元格中的状态。我确实想分享一些我为带有 select 标签而不是常规输入标签的单元格创建的代码:

import React from "react";

const SelectCell = ({ 
    row,
    column,
    value: initialValue,
    updateData,
    ddOptions
}) => {
    let options = <option key={"productLoading"} value={""}>Loading...</option>
    if (ddOptions) {
        options = ddOptions.map((prod) => (
      <option key={prod.id} value={prod.id}>
        {prod.name}
      </option>
    ));
    };
  return (
    <select value={initialValue} onChange={(e) => updateData(column, row, e.target.value)}>
      {options}
    </select>
  );
};

export default SelectCell;

然后在我的 table 实例上定义我的 ddOptions:

  const ddOptions = props.ddOptions; 
  const tableInstance = useTable(
    {
      columns,
            data,
            defaultColumn,
            updateData,
            ddOptions
    },
    useSortBy,
        usePagination,
        updateData,
        
  );

随着 ddOptions 以这种格式从任何地方传递:

[
    {
        value: 1,
        name: "Test Name"
    },
    {
        value: 2,
        name: "Test Name 2"
    },
    {
        value: 3,
        name: "Test Name 3"
    },
]