LoginSignup
0
0

More than 3 years have passed since last update.

useGlobalState

Posted at
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;
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0