【问题标题】:Accessing context from useEffect从 useEffect 访问上下文
【发布时间】:2019-05-21 14:04:24
【问题描述】:

我有一个上下文,用于在我的应用程序执行长时间运行的任务时显示整页微调器。

当我尝试在useEffect 中访问它时,我收到react-hooks/exhaustive-deps ESLint 消息。例如,以下代码虽然按预期工作,但指出 busyIndicator 是缺少的依赖项:

const busyIndicator = useContext(GlobalBusyIndicatorContext);

useEffect(() => {
    busyIndicator.show('Please wait...');
}, []);

This 文章建议我可以使用 useCallback 包装函数,如下所示:

const busyIndicator = useContext(GlobalBusyIndicatorContext);
const showBusyIndicator = useCallback(() => busyIndicator.show('Please wait...'), []);

useEffect(() => {
    showBusyIndicator();
}, [showBusyIndicator]);

虽然这可行,但它已将问题移至 useCallback 行,该行现在抱怨缺少依赖项。

在这种情况下可以忽略 ESLint 消息还是我错过了什么?

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    如果您的busyIndicator 在组件的生命周期内没有更改,您可以简单地将其作为依赖项添加到useEffect

    const busyIndicator = useContext(GlobalBusyIndicatorContext);
    
    useEffect(() => {
        busyIndicator.show('Please wait...');
    }, [busyIndicator]);
    

    如果busyIndicator 可以更改并且您不想看到错误,那么您可以使用useRef 挂钩:

    const busyIndicator = useRef(useContext(GlobalBusyIndicatorContext));
    
    useEffect(() => {
        busyIndicator.current.show('Please wait...');
    }, []);
    
    

    useRef() Hook 不仅仅适用于 DOM 引用。 “ref”对象是一个通用容器,其当前属性是可变的并且可以保存任何值,类似于类上的实例属性。 read more

    【讨论】:

    • 谢谢,我已经独立使用了useRef和useContext,但我从来没有想过它们可以一起使用
    • @Newm useRef 技巧真的很棒,为我解决了问题......谢谢!两年后,我在这里问您是否有足够的理解来解释为什么它可以解决问题?非常想知道这有什么不同。
    • 刚刚发现了这个技巧,它奏效了。 @ogg130 它起作用的原因是 useRef 创建了一个在组件的生命周期内持续存在的引用 - 来自文档 reactjs.org/docs/hooks-reference.html#useref “useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传递的参数(initialValue)。返回的对象将在组件的整个生命周期内持续存在。”通常你会看到它与元素的引用一起使用,但你可以将它用于很多事情。
    【解决方案2】:

    无需将您的 useContext 包装在 useRef Hook 中。 您可以更新您的上下文数据,只需调用 useEffect Brackets 像这样。

    const comingData = useContext(taskData);
    
    useEffect(() => {
    console.log("Hi useEffect");
    }},[comingData]); //context data is updating here before render the component
    

    【讨论】:

    • 这个例子不会导致组件渲染。如果 useEffect 中有任何会触发重新渲染的内容(例如,使用选择器调度存储、更新状态),则组件重新渲染将创建对 useContext 的新引用,从而导致 useEffect 再次运行,并创建无限环形。至少那是发生在我身上的事情。使用 useRef 很好地解决了它
    • console.log 将在每次任何事件更新上下文时触发,在我的情况下,它在几秒钟内为我添加了 +800MB 的内存
    猜你喜欢
    • 2020-08-19
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2010-09-08
    • 2020-04-26
    • 2011-06-07
    相关资源
    最近更新 更多