Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix: Context Provider not passing new context values down to children

i'm new to using React Hooks and React Context and I was wondering why my Context Provider doesn't seem to pass down the new values to a child component. I have it set up where the initial value "ColorContext" is 'red' but I want the value of "ColorContext" in the button to be 'green'. However, when I try to do so, the "ColorContext" value does not change and stays 'red.'

Here is the link to my code: 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'));
like image 285
Derek Wu Avatar asked Dec 23 '22 22:12

Derek Wu


2 Answers

See Hook Rules:

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders.

Thus, have a new consuming component using useContext hook as a good practice.

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>
  )
};
like image 123
Joseph D. Avatar answered Dec 26 '22 01:12

Joseph D.


You need wrap App component with context.

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'));
like image 25
Giang Le Avatar answered Dec 25 '22 23:12

Giang Le