【问题标题】: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'));

【问题讨论】:

    标签: javascript reactjs react-hooks react-context


    【解决方案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>
          );
          

          【讨论】:

            猜你喜欢
            • 2020-05-20
            • 1970-01-01
            • 2015-06-29
            • 2019-10-17
            • 1970-01-01
            • 1970-01-01
            • 2019-09-19
            • 2011-10-27
            • 1970-01-01
            相关资源
            最近更新 更多