Вы можете просто использовать одного провайдера и передавать требуемые значения как объект
export const StoreContext = React.createContext({});
const Store = ({ children }) => {
const [lang, setLang] = useState("javascript");
const [font, setFont] = useState("mono-space");
const [fontSize, setFontSize] = useState("16px");
return (
<StoreContext.Provider value={{lang, setLang, font, setFont, fontSize, setFontSize}}>
{children}
</StoreContext.Provider>
);
};
Также вместо использования useState вы можете изменить приведенное выше, чтобы использовать useReducer и сделать его еще более простым API
const initialState= {
lang: 'javascript',
font: 'mono-space',
fontSize: '16px',
}
const reducer = (state, action) => {
switch (action.type) {
case 'SET_LANG': return {...state, lang: action.payload}
case 'SET_FONT': return {...state, font: action.payload}
case 'SET_FONTSIZE': return {...state, fontSize: action.payload}
default: return state;
}
}
export const StoreContext = React.createContext({});
const Store = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StoreContext.Provider value={[state, dispatch]}>
{children}
</StoreContext.Provider>
);
};
а в детском можно использовать как
const Child = () => {
const [state, dispatch] = useContext(StoreContext);
const handleChange = (size) => {
dispatch({type: 'SET_FONTSIZE', payload: size})
}
....
}