React-在组件的生命周期中,`useState`挂钩的设置器是否可以更改?

时间:2019-07-24 10:27:06

标签: reactjs react-hooks

useState的设置方法在组件寿命期间是否可以更改?

例如,假设我们有一个useCallback,它将更新状态。 如果设置器能够更改,则必须将其设置为回调的依赖项,因为回调使用它。

const [state, setState] = useState(false);
const callback = useCallback(
    () => setState(true),
    [setState] // <-- 
);

2 个答案:

答案 0 :(得分:2)

简短的回答是,不,useState() 的 setter 不能更改,React docs explicitly guarantee this 甚至提供示例证明可以省略 setter。

我建议您不要在 useCallback() 的依赖项列表中添加任何内容,除非您知道它的值会改变。就像您不会添加从模块或模块级函数导入的任何函数、在组件外部定义的常量表达式等一样。添加这些内容只是多余的,并且会使您的处理程序更难以阅读。

说了这么多,这都非常特定于 useState() 返回的函数,并且没有理由将该推理线扩展到每个可能返回一个功能。原因是 React 文档明确保证了 useState() 及其 setter 的稳定行为,但它没有说任何自定义钩子都必须如此。

React hooks 仍然是一种新的实验性概念,我们需要确保彼此鼓励,使它们尽可能具有可读性,更重要的是,了解它们的实际作用以及原因。如果我们不这样做,它将被视为证明钩子是一个“坏主意”的证据,这将禁止采用和更广泛地理解它们。那会很糟糕;根据我的经验,它们倾向于为 React 通常关联的基于类的组件提供更简洁的替代方案,更不用说它们可以允许使用类根本不可能实现的组织技术这一事实。

答案 1 :(得分:1)

设置器功能在组件寿命期间不会更改

From Hooks FAQ:

  

(保证setCount函数的身份是稳定的,因此可以安全省略。)

setState返回的setter函数(useState)会在组件重新安装时发生更改,但是无论哪种方式,callback都会获得一个新实例。

这是一个好习惯,尽管在​​大多数情况下并不需要在依赖项数组([setState])中添加状态设置器。

例如,在使用自定义挂钩时,例如useDispatch of react-redux,如果没有以下内容,您可能会得到不希望的行为:

// Custom hook
import { useDispatch } from "react-redux";

export const CounterComponent = ({ value }) => {
  // Always new instance
  const dispatch = useDispatch();

  // Should be in a callback
  const incrementCounter = useCallback(
    () => dispatch({ type: "increment-counter" }),
    [dispatch]
  );

  return (
    <div>
      <span>{value}</span>

      // May render unnecessarily due to the changed reference
      <MyIncrementButton onIncrement={dispatch} />

      // In callback, all fine
      <MyIncrementButton onIncrement={incrementCounter} />
    </div>
  );
};