在对数组进行排序并传递它之后,React 钩子 useState/setState 不起作用

Posted

技术标签:

【中文标题】在对数组进行排序并传递它之后,React 钩子 useState/setState 不起作用【英文标题】:React hooks useState/setState not working after sorting the array and passing it 【发布时间】:2020-04-26 00:07:46 【问题描述】:

我有 React 应用程序并且我正在使用 React 钩子:

  const [companies, setCompanies] = useState([]);

我正在获取数据,而“公司”正在填满数据。我还有另一个按 NetIncome 排序数据的按钮:

 const sortByIncome = e => 
    const el = document.getElementById("sort-selectbox");
    const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
    console.log(arr);
    setCompanies(arr);
  ;

问题在于 setCompanies 不会重新渲染。在 console.log 我可以看到该数组已正确排序,即使我 console.log(companies) 我也可以看到它也已排序。但注意发生在界面中。另外,如果我输入相同的代码:

const sortByIncome = e => 
    const el = document.getElementById("sort-selectbox");
    const arr = companies.sort((a, b) => (a.NetIncome > b.NetIncome ? -1 : 1));
    console.log(arr);
    setCompanies([]);
  ;

但是传递给 setCompanies 空数组,它会立即工作并且什么都不显示(我有渲染函数,可以将公司作为参数)。 那么为什么它不适用于传递 arr 呢?是不是因为我传递的是同一个数组,但只是排序了?

【问题讨论】:

你如何呈现你的列表?如果将其映射到 JSX 元素列表,这些元素是否有键? 此外,这种排序可能会导致结果不一致,因为当两个值相同时您不会返回 0。您可以将其更改为:companies.sort((a, b) => a.NetIncome - b.NetIncome) @IsmaelPadilla 我是这样做的: const CompaniesResult = array => if (array !== undefined) return array.map((item, index) => return ; ); ; 你不应该使用索引作为键!特别是当您的物品可以重新订购时。阅读:reactjs.org/docs/lists-and-keys.html#keys 不应该是setCompanies([...arr])吗? 【参考方案1】:

这里:

    const arr = companies.sort((a, b) => //...

Array.prototype.sort 对数组就地进行排序,即对原始对象进行变异。引用没有改变,突变也没有被注意到。改为这样做

    const arr = [...companies].sort((a, b) => //...

【讨论】:

感谢您帮助解决这个棘手的部分。您的解决方案非常完美。【参考方案2】:

函数sortByIncome 内的钩子变量companies 的值将始终是您的钩子([]) 的初始值,并且永远不会收到使用setCompanies 设置的新值。

解决问题的方法是将函数 sortByIncome 包装在 useCallback 钩子中,并将钩子变量 companies 作为依赖项。这将确保函数始终使用companies 的当前值。

const sortByIncome = React.useCallback(e => 

   // Using `companies` will always result in the current value

, [companies]);

useCallback documentation

【讨论】:

以上是关于在对数组进行排序并传递它之后,React 钩子 useState/setState 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

用 Jest 模拟 React 自定义钩子

Flask---钩子函数

如何在 React 中使用带有钩子的 onChange 更新数组元素?

React 钩子形式 - 对话框内的字段数组(材料 UI)

React Redux 问题传递状态值

将 React Hook 传递给功能组件