useState 的 setter 能否在组件生命周期内更改?
例如,假设我们有一个useCallback
将更新状态。如果 setter 能够更改,则必须将其设置为回调的依赖项,因为回调使用它。
const [state, setState] = useState(false);
const callback = useCallback(
() => setState(true),
[setState] // <--
);
useState 的 setter 能否在组件生命周期内更改?
例如,假设我们有一个useCallback
将更新状态。如果 setter 能够更改,则必须将其设置为回调的依赖项,因为回调使用它。
const [state, setState] = useState(false);
const callback = useCallback(
() => setState(true),
[setState] // <--
);
setter函数在组件寿命期间不会改变。
( setCount 函数的身份保证是稳定的,所以省略是安全的。)
setter 函数 ( setState
) 从useState
组件重新安装时的更改返回,但无论哪种方式,callback
都将获得一个新实例。
[setState]
使用custom-hooks时,在依赖数组 ( ) 中添加状态设置器是一个很好的做法。例如,在每次渲染useDispatch
时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>
);
};
简短的回答是,不,useState的二传手()不能改变,以及做出react的文档明确保证这一点,甚至提供实例证明二传手可以省略。
我建议您不要在useCallback()的依赖项列表中添加任何内容,除非您知道它的值可以更改。就像您不会添加从module或module级函数导入的任何函数、在组件外部定义的常量表达式等一样。添加这些东西只是多余的,并且会使您的处理程序更难以阅读。
话虽如此,这一切都非常特定于useState()返回的函数,并且没有理由将该推理线扩展到可能返回函数的每个可能的自定义钩子。原因是 React 文档明确保证useState()及其 setter的稳定行为,但并没有说任何自定义钩子都必须如此。
React hooks 仍然是一种新的实验性概念,我们需要确保我们相互鼓励,使它们尽可能具有可读性,更重要的是,了解它们的实际作用以及原因。如果我们不这样做,它将被视为证明钩子是一个“坏主意”的证据,这将禁止采用和更广泛地理解它们。那会很糟糕;根据我的经验,他们倾向于为 React 通常关联的基于类的组件提供更清洁的替代方案,更不用说他们可以允许使用类根本不可能实现的组织技术的事实。