I'm using Context API to store global value like userId to share between ponents across entire application.
Here's what the context.js looks like:
import React, { useState } from 'react';
const AppContext = React.createContext({
date: new Date(),
userId: null,
groupId: null,
setAppContext: () => {},
});
export const AppContextProvider = (props) => {
const initState = {
date: new Date(),
userId: null,
groupId: null,
setAppContext: (appContext) => {
console.log(state); // this line always log initial state value after first update
setState({ ...state, ...appContext });
},
}
const [state, setState] = useState(initState);
return (
<AppContext.Provider value={state}>
{props.children}
</AppContext.Provider>
)
}
export default AppContext;
Basically I'm trying to use one big context to hold all value that I use together and access them in child ponents like this:
// access value and the setter
const { userId, setAppContext } = useContext(AppContext);
// setting value
setAppContext({
userId: newUserId,
});
The problem is, "state" variable in the setter function doesn't seems to update and when I try to set new value like above, other values get overwrite with its initial value (e.g. userId get update but the rest return to null), which I guess I must do something wrong and I still have no idea.
Any advice would be much appreciated.
I'm using Context API to store global value like userId to share between ponents across entire application.
Here's what the context.js looks like:
import React, { useState } from 'react';
const AppContext = React.createContext({
date: new Date(),
userId: null,
groupId: null,
setAppContext: () => {},
});
export const AppContextProvider = (props) => {
const initState = {
date: new Date(),
userId: null,
groupId: null,
setAppContext: (appContext) => {
console.log(state); // this line always log initial state value after first update
setState({ ...state, ...appContext });
},
}
const [state, setState] = useState(initState);
return (
<AppContext.Provider value={state}>
{props.children}
</AppContext.Provider>
)
}
export default AppContext;
Basically I'm trying to use one big context to hold all value that I use together and access them in child ponents like this:
// access value and the setter
const { userId, setAppContext } = useContext(AppContext);
// setting value
setAppContext({
userId: newUserId,
});
The problem is, "state" variable in the setter function doesn't seems to update and when I try to set new value like above, other values get overwrite with its initial value (e.g. userId get update but the rest return to null), which I guess I must do something wrong and I still have no idea.
Any advice would be much appreciated.
Share asked Jun 20, 2020 at 12:53 DANKESTDANKEST 411 gold badge1 silver badge3 bronze badges1 Answer
Reset to default 3In this case:
const AppContext = React.createContext({
date: new Date(),
userId: null,
groupId: null,
setAppContext: () => {},
});
setAppContext
is just a function, it is not from React API.
In order to change state, and make React to be aware of its change, you need to use any setter function from React API.
Like setter function returned from
useState()
.
See similar question here.
So, in your case, to solve it you need to pass a real setter:
const initState = {
date: new Date(),
userId: null,
groupId: null,
};
const AppContext = React.createContext();
export const AppContextProvider = (props) => {
const [state, setState] = useState(initState);
const setAppContext = (appContext) => {
console.log(state);
setState({ ...state, ...appContext });
};
return (
<AppContext.Provider value={{ ...state, setAppContext }}>
{props.children}
</AppContext.Provider>
);
};
export default AppContext;