React Context

떡ol·2023년 8월 28일

Context란

React에서 컴포넌트에 프로퍼티를 넘길때 하나씩 나열에서 사용해왔습니다.

// 이렇게 나열하던것을 깔끔하게 정리해봅시다.
return (
	<DiaryList diaryList={data} onRemove={onRemove} onEdit={onEdit}/>
);

다만 React가 부모에서 부터 아래로 인자를 내려주는 drill down 형식이라 props가 많아질수록 코드는 복잡해지고 길어지며, 관리하기도 힘들어지겠지요..
이러한 문제를 해결하기위해 만든 것이 Context입니다.

사용하기

Context는 생성과 사용으로 나눠집니다. 부모쪽에서 보낼때는 createContext에 담아서 보내면 되고 자식쪽에서는 useContext로 불러와서 사용하면 됩니다.

createContext

export const DiaryStateContext = createContext(null);
export const DiaryDispatchContext = createContext(null);

named export vs export default
default는 말그대로 default다 파일안에서 하나만 지원되므로 import 이름을 아무렇게나 해도 가져온다.
named는 export를 여러개 가능하다. 즉, 해당 이름을 정확히 import 해야한다.

// default ex
export default App;

import dkanfjgrpskrksmd from "./App";
// named ex
export {abc, def, ggg};

import abc from "./index";
import def from "./index";
import ggg from "./index";

우선 null 객체로 상단에 생성해주신다음에, 컴포넌트 쪽에 .Provider를 붙혀 값을 보내주시면 됩니다.

    return (
        <DiaryDispatchContext.Provider value={memoizedDispatch}> // 하나씩
        <DiaryStateContext.Provider value={data}> // 하나씩 사용합니다.
            <div className="App">
                <DiaryEditor /*onCreate={onCreate} 이건 이제 필요없습니다.*/ />
                <div>전체 일기 : {data.length}</div>
                <div>좋은 일기 : {goodCount}</div>
                <div>나쁜 일기 : {badCount}</div>
                <div>좋은 일기 비율 : {goodRatio}</div>
                <DiaryList /*diaryList={data} onRemove={onRemove} onEdit={onEdit}*/ />
            </div>
        </DiaryStateContext.Provider>
        </DiaryDispatchContext.Provider>
    );

해당 예제는 두가지로, data와 dispatcher기능을 각각 따로 분류해서 넣었습니다.

	//dispatch는 다음과 같이 객체와 useMemo로 묶어야 re-render가 안되겠죠?
    const memoizedDispatch = useMemo(() => {
        return {onCreate, onRemove, onEdit};
    }, []);

data와 dispatch를 한번에 담아서 보내면 되는거 아닌가라고 생각할 수 있지만, 그렇게 되면 data가 바뀔때마다 나머지 3개의 dispatch도 계속 re-render가 됩니다. 필수적으로 data와 dispatch를 따로 구분하여 보내주셔야합니다.

createContext

다음과 같이 props값을 불러와 사용해주시면 됩니다.

import {DiaryDispatchContext} from "./App";


const DiaryEditor = (/*{onCreate} 필요없습니다.*/) => {
	const {onCreate} = useContext(DiaryDispatchContext);
    
    console.log("안녕하세요 생성되었습니다.")
    
}
profile
하이

0개의 댓글