如何使用 React Hooks 更新依赖于其他状态的状态

dra*_*fly 5 reactjs react-hooks

所以我有这个自定义钩子:

import sortBy from 'lodash/fp/sortBy';
import { useState, useEffect } from 'react';

/**
 * Custom effect that enables data sorting.
 * It is triggered every time when sort order or data has changed.
 *
 * @param {*} initialSort
 * @param {*} data
 */
function useSorting(initialSort, data) {
  const [sortOrder, setSortOrder] = useState(initialSort);
  const [sortedData, setSortedData] = useState([]);
  useEffect(() => setSortedData(sortBy(sortOrder, data)), [data, sortOrder]);

  return [sortedData, sortOrder, setSortOrder];
}

export default useSorting;
Run Code Online (Sandbox Code Playgroud)

它接受要排序的数据和排序顺序。每次通过更改排序顺序setSortOrderdata提供new 时,它都应该进行排序和更新sortedData

这是正确的方法吗?我的意思是,有一个useEffect正在监听[data, sortOrder]?

如果没有 React 钩子,我会使用componentDidUpdate并手动检查sortOrder或 是否data已更改并this.setState使用 new sortedData。看起来它做了类似的事情

Bea*_*oot 2

你的例子应该可以工作,这就是按顺序发生的事情,比如说当你传递 newdata或你使用时setSortOrder

1 - 你到达你的钩子代码内

2 - 你钩子用来setSortedData更新它的sortedData状态

3 - 它返回一个陈旧的sortedData组件(因为它是useState在修改之前读取的)

4 - 调用启动setSortedData,更改状态中的数据,触发组件的新渲染,这将再次使用您的钩子,并且该钩子将提供正确版本的sortedData.

简而言之,您有一个额外的渲染。如果你想防止这种情况,你可以使用useMemo,如下所示:

function useSorting(initialSort, data) {
  const [sortOrder, setSortOrder] = useState(initialSort);
  const sortedData = useMemo(() => sortBy(sortOrder, data), [data, sortOrder]);

  return [sortedData, sortOrder, setSortOrder];
}
Run Code Online (Sandbox Code Playgroud)

您的组件将立即获取排序后的数据,而无需经过额外的渲染循环,并且您仍然可以享受仅在相关信息发生更改时才调用排序函数的好处( ,datasortOrder