useGlobalState.jsx
import React, { useEffect, createContext, useReducer, useContext, useDebugValue } from 'react';
/* Action Types */
const SET_VALUE = 'SET_VALUE';
/* Define a context and a reducer for updating the context */
const GlobalStateContext = createContext();
const globalStateReducer = (state, action) => {
const { key, data } = action.payload;
switch (action.type) {
case SET_VALUE:
return {
...state,
...{ [key] : data },
};
default:
return state;
}
};
export const GlobalStateProvider = ({ children }) => {
const [ state, dispatch ] = useReducer(globalStateReducer, {});
return (
<GlobalStateContext.Provider value={[ state, dispatch ]}>
{ children }
</GlobalStateContext.Provider>
);
};
const useGlobalState = (key, initialValue) => {
const [ state, dispatch ] = useContext(GlobalStateContext);
const setGlobalState = data => {
dispatch({
type: SET_VALUE,
payload: { key, data },
});
};
const getState = () => {
const resultState = state && state[key] ? state[key] : initialValue;
return resultState;
};
useEffect(() => {
if ( ! state || ! state.hasOwnProperty(key)) {
setGlobalState(initialValue !== undefined ? initialValue : null);
}
}, [ initialValue ]);
return [
getState(),
setGlobalState,
];
};
export default useGlobalState;
index.jsx
import React from 'react';
import { render } from 'react-dom';
import '@project/initialize';
import { GlobalStateProvider } from './useGlobalState';
import Contents from './Contents';
const App = () => (
<GlobalStateProvider>
<Contents />
</GlobalStateProvider>
);
render(<App />, document.getElementById('root'));
Contents.jsx
import React from 'react';
import useGlobalState from './useGlobalState';
const Contents = () => {
const defaultValue = null;
const [ globalValue, setGlobalValue ] = useGlobalState('key', defaultValue);
return (
<div>{ globalValue }</div>
)
};
export default Contents;