본문 바로가기
JavaScript/React

ContextAPI 사용자 정의 훅이 있는 팩토리패턴

by 봉이로그 2024. 4. 10.
  • createStateContext를 구현
    • 초기값을 받아 상태를 반환하는 useValue 사용자 정의 훅 사용
      • useState를 사용하여 state와 setState함수 튜플을 할당
    • Provider, 사용자 정의 훅을 튜플로 반환
    • 반복적인 코드를 줄이면서 위의 방법과 동일한 기능을 제공

 

// createStateContext
const createStateContext = <Value, State>(useValue: (init? : Value) => State) => {

	const StateContext = createContext<State | null>(null);
	
	// 공급자
	const StateProvider = ({
		initialValue,
		children
	} : {
		initialValue?: Value;
		children?: ReactNode;
		}
	) => (
		<StateContext.Provider value={useValue(initialValue)}>
				{children}
		</StateContext.Provider>
	)
	
	// 사용자 정의 훅
	const useContextState = () => {
		const value = useContext(StateContext);
		if(value === null) throw new Error("Provider Missing");
		return value;
	};
	
	return [StateProvider, useContextState] as const;
};

...


const useNumberState = (init?: number) => useState(init || 0);

// 원하는 만큼 상태 컨텓스트를 생성
const [Count1Provider, useCount1] = createStateContext(useNumberState);
const [Count2Provider, useCount2] = createStateContext(useNumberState);


const Counter1 = ()=> {
	const [count1, setCount1] = useCount1();
	...
	<button onClick={()=> setCount1((c)=> c + 1))}>{count1}</button>
}

const Counter2 = ()=> {
	const [count2, setCount2] = useCount2();
	...
	<button onClick={()=> setCount2((c)=> c + 1))}>{count2}</button>
}

const Parent = () => (
	<>
    <Counter1 />
    <Counter2 />
	</>
)

const App = () => (
    <Counter1Provider>
        <Counter2Provider>
            <Parent />
        </Counter2Provider>				
    </Counter1Provider>
)