【问题标题】:How to make useEffect only run once on component mount without lying to React?如何让 useEffect 只在组件挂载上运行一次而不对 React 撒谎?
【发布时间】:2020-12-02 16:51:48
【问题描述】:

如果我希望useEffect 只在组件挂载上运行一次,那么正确的做法是什么?检查以下示例:

const UseEffectCounter1 = () => {
    const [count, setCount] = useState(0);
    useEffect(() => {
        document.title = `You clicked ${count} times`;
    }, []);
    return (
        <div>
            <button onClick={() => {setCount(count + 1)}}>+1</button>
        </div>
    )
}

由于[] 被作为依赖数组传递,因此阻止了重新渲染。代码运行良好,没有错误。 'You clicked 0 times'只显示一次,点击按钮什么都不做,符合'只在组件挂载上运行一次'的目的。

然而,这是对 React 的欺骗,并且在 Dan Abramov 的文章 here 中不推荐。我应该将依赖传递给依赖数组,它被警告为React Hook useEffect has a missing dependency: 'count'。但是,如果我在依赖数组中传递[count]useEffect 在组件挂载后开始更新。

使useEffect 仅在组件挂载时更新的正确方法是什么?

【问题讨论】:

  • 对于您发布的示例,使 useEffect 挂钩依赖于count 没有任何意义;你应该简单地拥有useEffect(() =&gt; { document.title = 'You clicked 0 times' }, []),这样你就没有依赖关系,所以你不会“撒谎”。可以分享一下实际情况吗?这将更容易理解是否以及如何列出依赖项。
  • @secan 这是实际情况,我试图了解 useEffect 依赖项。如果让 useEffect 依赖于count 没有意义,为什么 React 会给我警告?
  • 因为你让钩子依赖于count,所以 React 正确地表明你没有列出所有的依赖关系。如果你在 useEffect 中删除了 count 的使用,并且你硬编码了你想要使用的固定值,React 将停止抱怨,因为你没有任何依赖
  • 新的 react 版本的钩子背后的主要目标在于同步的概念,而不是生命周期。他们试图获得组件的心智模型,这是关于保持和思考同步方面的逻辑,而不是生命周期的方式。所以,我们永远不要考虑组件的挂载和卸载方式

标签: javascript reactjs


【解决方案1】:

正如评论中提到的,如果您不打算在每次计数更改时更新标题,那么使 useEffect 挂钩依赖于 count 是没有意义的。代码可能是:

const UseEffectCounter1 = () => {
    const [count, setCount] = useState(0);
    useEffect(() => {
        document.title = 'You clicked 0 times';
    }, []);
    return (
        <div>
            <button onClick={() => {setCount(count + 1)}}>+1</button>
        </div>
    )
}

无论如何,如果你真的想避免硬编码值,你可以这样做:

const UseEffectCounter1 = () => {
    const initCount = 0;
    const [count, setCount] = useState(initCount);
    useEffect(() => {
        document.title = `You clicked ${initCount} times`;
    }, [initCount]);
    return (
        <div>
            <button onClick={() => {setCount(count + 1)}}>+1</button>
        </div>
    )
}

由于initCount 永远不会改变,useEffect 挂钩只会被触发一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    • 2020-05-21
    • 1970-01-01
    相关资源
    最近更新 更多