React - useState 的 setter 函数是否可以更改?

React - Is useState 's setter function able to change?

useState 的 setter 可以在组件生命周期内改变吗?

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

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

setter功能在组件生命周期内不会改变

From Hooks FAQ:

(The identity of the setCount function is guaranteed to be stable so it’s safe to omit.)

useState 返回的 setter 函数 (setState) 在组件 re-mount 上发生了变化,但无论哪种方式,callback 都会得到一个新实例.

使用custom-hooks时,在依赖数组([setState])中添加状态setter是一个很好的做法 。例如,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>
  );
};

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

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

综上所述,这都是非常特定于由 useState() 编辑的 return 函数,没有理由扩展该行推理每个可能 return 函数的自定义挂钩。原因是 React 文档明确保证 useState() 及其 setters 的稳定行为,但它 not 说这同样适用于任何自定义挂钩。

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