如何解决:上下文提供程序未将新的上下文值传递给子级

Posted

技术标签:

【中文标题】如何解决:上下文提供程序未将新的上下文值传递给子级【英文标题】:How to fix: Context Provider not passing new context values down to children 【发布时间】:2019-12-03 05:25:43 【问题描述】:

我是使用 React Hooks 和 React Context 的新手,我想知道为什么我的 Context Provider 似乎没有将新值传递给子组件。我将其设置为初始值“ColorContext”为“红色”,但我希望按钮中“ColorContext”的值为“绿色”。但是,当我尝试这样做时,“ColorContext”值不会改变并保持“红色”。

这是我的代码的链接: https://stackblitz.com/edit/react-8mhqwu

import React,  Component, useState, useContext, createContext  from 'react';
import  render  from 'react-dom';

const ColorContext = createContext('red')


const App = (props) => 

  return (
    <div className="app">
      <ColorContext.Provider value= 'green'>
        <button
        style = backgroundColor: useContext(ColorContext)
        >
          Click here
        </button>
      </ColorContext.Provider>
    </div>
  )


render(<App />, document.getElementById('root'));

【问题讨论】:

【参考方案1】:

见Hook Rules:

仅在顶层调用 Hooks

不要在循环、条件或嵌套函数中调用 Hooks。相反,请始终在 React 函数的顶层使用 Hooks。通过遵循此规则,您可以确保每次组件呈现时都以相同的顺序调用 Hook。

因此,使用 useContext 钩子作为一个好的做法有一个新的消费组件。

const ColorContext = createContext('red');

const Button = () => 
  const value = useContext(ColorContext);
  return (
    <button style = backgroundColor: value
    >
      value
    </button>
  );
;

const App = (props) =>   
  return (
    <div className="app">
      <ColorContext.Provider value='blue'>
        <Button />
      </ColorContext.Provider>
    </div>
  )
;

【讨论】:

【参考方案2】:

你需要用上下文包裹App 组件。

const App = (props) => 

  return (
    <div className="app">
        <button
        style = backgroundColor: useContext(ColorContext)
        >
          Click here
        </button>
    </div>
  )


render(<ColorContext.Provider value= 'green'><App /></ColorContext.Provider>, document.getElementById('root'));

【讨论】:

【参考方案3】:

来自react useContext docs:

当组件上方最近的&lt;MyContext.Provider&gt; 更新时,此 Hook 将触发重新渲染,并将最新的上下文值传递给该 MyContext 提供程序。 ...

useContext(MyContext) 只允许您读取上下文并订阅其更改。您仍然需要树中的&lt;MyContext.Provider&gt; above 来提供此上下文的值。

这就是说,上下文需要高于您要更新的组件。 IE。在您的示例中,它必须是 &lt;App /&gt; 组件的父级。

因此,Giang 是对的,您需要在 ColorContext.Provider 组件中定义 &lt;App /&gt;

【讨论】:

【参考方案4】:

因为你 useContextApp 组件中。所以它会在树中找到调用组件(App)上方的nearest context。结果没有找到。所以它采用默认值('red')而不是您在App 组件的上下文中传递的值('green')。您需要将按钮包装到一个新组件中,并在该组件中 useContext

const ContextButton = () => (
  <button type="button" style= backgroundColor: useContext(ColorContext) >
    Click here
  </button>
);

【讨论】:

以上是关于如何解决:上下文提供程序未将新的上下文值传递给子级的主要内容,如果未能解决你的问题,请参考以下文章

React学习笔记 Redux

将 NSManagedObject 传递给子上下文不起作用

SwiftUI 将数组的元素作为绑定传递给子视图

如何通过事件将数据从父级传递给子级

Vue 组件:如何将数据从父级传递给子级

如何在Flask的构架中传递logger给子模块