I am trying to get my child component to look for the global state. As of now, I can log out my global state, I can see that it has been updated, but my components are not updating with the new value. I am not getting any errors but also have had a hard time find a good solution. I have the full repo(very small with only 1 component) if it helps here: https://github.com/jaysnel/context-api-react
Is there any reason my ChangeColor.js file is not updating with the new state change?
UpdateColor.js
import React, { useReducer, useEffect } from 'react'
import { useAppContext } from '../public/context/context'
export default function UpdateColor() {
let { myGlobaData } = useAppContext();
const [state, dispatch] = useReducer(reducer, myGlobaData);
function reducer(state, action) {
let newState = state.slice();
console.log(state);
if(newState !== undefined) {
switch(action.type) {
case 'UPDATE_COLOR':
newState[0].color = 'green';
return newState;
default:
throw new Error();
}
}
}
return (
<div>
<button onClick={() => dispatch({type: 'UPDATE_COLOR'})}>Update Color</button>
</div>
)
}
ChangeColor.js
import React from 'react'
import { useAppContext } from '../public/context/context'
export default function ChangeColor() {
const { myGlobaData } = useAppContext();
console.log("ChangeColor.js", myGlobaData)
return (
<div>
<h2 style={{color: myGlobaData[0].color}}>I Change Colors Based On Global State.</h2>
</div>
)
}
context.js
import { createContext, useContext } from 'react';
const AppContext = createContext();
export function AppWrapper({ children }) {
const state = {
myGlobaData: [
{
color: 'red',
text: 'new text new me'
}
],
}
return (
<AppContext.Provider value={state}>
{children}
</AppContext.Provider>
);
}
export function useAppContext() {
return useContext(AppContext);
}
I guess, your issue where did you used the reducer. Component ChangeColor.js
don't know what are you doing inside UpdateColor.js
. The solution is if put the reducer into global context context.js
and then you have to acsess your reducer globally.
I did created and pushed to github working example with two different approaches to using an actions reducer. working example
UpdateColor.js
import { useAppContext } from '../public/context/context'
export default function UpdateColor() {
const { dispatch } = useAppContext();
const withPayload = () => {
dispatch({
type: 'UPDATE_COLOR_WITH_PAYLOAD',
payload: {color: 'blue', text: 'new text from updateColor.js'}})
}
const intoReducer = () => {
dispatch({type: 'UPDATE_COLOR_INTO_REDUCER'})
}
return (
<div>
<button onClick={withPayload}>Update Color with payload</button>
<button onClick={intoReducer}>Update Color into reducer</button>
</div>
)
}
ChangeColor.js
import { useAppContext } from '../public/context/context'
export default function ChangeColor() {
const { state } = useAppContext();
return (
<div>
<h2 style={{color: state.color}}>I Change Colors Based On Global State.</h2>
<p style={{textAlign: 'center'}}>{state.text}</p>
</div>
)
}
context.js
import { createContext, useContext, useReducer } from 'react';
const AppContext = createContext();
export function useAppContext() {
return useContext(AppContext);
}
function reducer(state, action) {
switch (action.type) {
case 'UPDATE_COLOR_WITH_PAYLOAD':
return action.payload;
case 'UPDATE_COLOR_INTO_REDUCER':
action.color = 'green';
action.text = 'new text from reducer';
return action;
default:
return state;
}
}
export function AppWrapper({ children }) {
const initialState = { color: 'red', text: 'new text new me' };
const [state, dispatch] = useReducer(reducer, initialState);
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
}