You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Formik useField与react-data-table-component触发无限循环问题求助

解决Formik + react-data-table-component的无限循环问题

问题场景

在Formik表单中使用react-data-table-component更新数值时,出现了无限循环:每当MyTable组件重渲染,selectableRowSelected回调会被触发,进而调用onSelectedRowsChange事件;在事件回调里执行helpers.setValue()更新Formik字段值后,又会触发组件再次重渲染,循环往复无法停止。

问题根源

selectableRowSelected会在组件每次重渲染时遍历所有行,判断每行的选中状态,这个过程会触发onSelectedRowsChange事件。如果直接在事件回调里调用helpers.setValue(),Formik的状态更新会立即触发组件重渲染,再次触发上述流程,最终形成无限循环。

解决方案

打破循环的核心是只在选中状态确实发生变化时,才执行Formik的状态更新,避免无意义的重渲染触发循环。同时要修正回调函数的依赖数组,确保能获取到最新的字段状态。

修改后的代码示例

function MyTable() {
  const [data, setData] = useState([]);
  const [field, meta, helpers] = useField({ name: "use" });

  useEffect(() => {
    fetch("https://reqres.in/api/users?page=1&per_page=3")
      .then((res) => res.json())
      .then((res) => setData(res.data));
  }, []);

  const handleChange = React.useCallback(({ selectedRows }) => {
    let selectedIds = selectedRows.map(row => parseInt(row.id)).sort();
    // 对比新选中ID与现有值,仅当不同时才更新
    const isValueChanged = JSON.stringify(selectedIds) === JSON.stringify(meta.value);
    if (!isValueChanged) {
      helpers.setValue(selectedIds, true);
    }
  }, [meta.value, helpers]); // 加入依赖,确保获取最新的字段值和Formik工具函数

  return (
    <DataTable
      title="User List"
      columns={columns}
      data={data}
      selectableRows
      selectableRowsHighlight
      onSelectedRowsChange={handleChange}
      selectableRowSelected={(row) => {
        return meta.value.includes(parseInt(row.id));
      }}
    />
  );
}

关键修改说明

  • 添加值对比逻辑:通过JSON.stringify比较新选中的ID数组与Formik存储的meta.value,仅当两者不同时才执行状态更新,避免无意义的重渲染。
  • 修正依赖数组:将meta.value和helpers加入useCallback的依赖列表,保证回调函数能获取到最新的字段状态和Formik工具方法,解决闭包导致的旧值问题。

内容的提问来源于stack exchange,提问作者free2idol1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 08:25:27