Skip to content

Instantly share code, notes, and snippets.

@iamchiwon
Created August 9, 2023 09:56
Show Gist options
  • Save iamchiwon/73fe63bcf3b3d98bbccf2996a7ea97af to your computer and use it in GitHub Desktop.
Save iamchiwon/73fe63bcf3b3d98bbccf2996a7ea97af to your computer and use it in GitHub Desktop.
React 전역 상태 관리 유틸 - context wrapper
/**
* Context 를 사용한 전역 상태 관리 유틸
*
* 주의: 상태 변경 시 AppStateProvider 하위의 모든 컴포넌트가 리렌더링 됨
*
* 사용법:
*
* <AppStateProvider>
* <App />
* </AppStateProvider>
*
*
* export default function Component() {
* const [lang, setLang] = useAppState('lang', 'en');
* return (
* <>
* <p>{lang}</p>
* <button onClick={() => setLang(() => 'ko')}>KO</button>
* <button onClick={() => setLang(() => 'en')}>EN</button>
* </>
* );
* }
*
*/
import React, { createContext, useContext, useState, useCallback } from "react";
const appContext = createContext({
state: {},
setState: (s: any) => {}
});
interface AppStateProviderProps {
children: React.ReactNode;
initialState?: any;
}
export default function AppStateProvider(props: AppStateProviderProps) {
const [appState, setAppState] = useState(props.initialState ?? {});
return (
<appContext.Provider
value={{
state: appState,
setState: (update: any) => setAppState(update)
}}
>
{props.children}
</appContext.Provider>
);
}
export function useAppState(keyName: string, defaultValue: any = undefined) {
const { state, setState } = useContext(appContext);
// @ts-ignore
const _state = state[keyName] ?? defaultValue;
const _setState = (f: (s: any) => any) =>
setState({ ...state, [keyName]: f(_state) });
return [_state, _setState];
}
export function useAppStateValue(
keyName: string,
defaultValue: any = undefined
) {
const { state } = useContext(appContext);
// @ts-ignore
return state[keyName] || defaultValue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment