【问题标题】:React - Is useState 's setter function able to change?React - useState 的 setter 函数可以改变吗?
【发布时间】:2019-12-02 11:28:56
【问题描述】:

useState 的 setter 是否能够在组件生命周期内改变?

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

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

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    setter 函数在组件生命周期内不会改变

    From Hooks FAQ:

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

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

    在使用 custom-hooks 时,在依赖数组 ([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>
      );
    };
    

    【讨论】:

    • 感谢丹尼斯的回答。当然,当一个组件被挂载时,钩子会被重置。我的意图只是在一个组件的生命周期内,所以我编辑了这个问题。此外,我的问题只针对useStatesetter。自定义钩子,因为它们是自定义的,所以我们当然应该准备好随时更改它们,除非他们的文档另有说明。但是因为一方面我没有看到 setState 钩子的文档这么说,但另一方面实验表明 setter 实例在一个组件的生命周期内不会改变,所以我在 Stackoverflow 上问这个问题。
    • built-in 钩子不会改变,但我必须注意自定义钩子。
    • 哦..?你说内置的钩子不会改变?请问来源是什么?也许你,如果你在 React 项目上工作?。 --- 您适合自定义挂钩,任何人都可能需要此信息。
    • 我添加了来自文档的引用,对于其他钩子,我在与 Dan Abramov 的这篇博文相关的地方读到它:overreacted.io/why-do-hooks-rely-on-call-order
    • > 例如,react-redux 的 useDispatch 在每次渲染时都会获得新实例,如果没有:文档要求不同:“只要相同的商店实例正在传递给 。” reactjs.org/docs/hooks-reference.html#usestate
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-12-06
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 1970-01-01
      • 2021-01-25
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多