1. 배경
- 특정 함수를 특정 컴포넌트를 거쳐서 원하는 컴포넌트에게 전달하는 작업은 리액트에서 흔함
- 3~4개 이상의 컴포넌트를 거쳐서 전달해야 한다면 매우 번거로움
- Context API와 dispatch를 사용하면 이러한 복잡한 구조를 해결할 수 있음
2. Context API
- 프로젝트에서 전역적으로 사용할 수 있는 값을 관리
- 상태 뿐만 아니라 값, 즉 함수, 외부 라이브러리 인스턴스, DOM 일 수 있음
사용 방법
const UserDispatch = React.createContext(null);
- createContext 파라미터로 Context의 기본 값 설정 가능
- Context를 만들면, Context 내부의 Provider라는 컴포넌트가 있는데, 이 컴포넌트를 통해서 Context 값을 정할 수 있음.
<UserDispatch.Provider value={dispatch}>...</UserDispatch.Provider>
- 이렇게 설정하면 Provider에 의해 감싸진 컴포넌트 중 어디서든지 Context 값을 다른 곳에서 조회하고 사용할 수 있음
순서
- Context 생성
export const UserDispatchContext = React.createContext();
- reducer 정의
function reducer(state, action) {
switch (action.type) {
case 'CREATE_USER':
return {
users: state.users.concat(action.user)
};
case 'TOGGLE_USER':
return {
...state,
users: state.users.map(user =>
user.id === action.id ? { ...user, active: !user.active } : user
)
};
case 'REMOVE_USER':
return {
...state,
users: state.users.filter(user => user.id !== action.id)
};
default:
return state;
}
}
- dispatch 생성
const [state, dispatch] = useReducer(reducer, initialState);
- context 사용하고자 하는 자식 컴포넌트 감싸기
<UserDispatchContext.Provider value={dispatch}>
{children}
</UserDispatchContext.Provider>
- UserDispatchContext 불러오기
import { UserDispatchContext } from './App';
- 부모 컴포넌트에서 보내 준 dispatch 가져오기
const dispatch = useContext(UserDispatchContext);
- 필요한 곳에 dispatch로 acition 보내기
onClick={() => {
dispatch({ type: 'TOGGLE_USER', id: user.id });
}}
정리
- Context로 감싸져 있는 곳에서 State, dispatch 등을 공유할 수 있음
- 감쌀 때 value가 state라면, state를 공유받을 수 있음
- 감쌀 때 value가 dispatch라면, dispatch를 공유받을 수 있음
- 부모에서 state, reducer가 정의되어 있음.
- 자식에서 context를 받아 연결되어 있는 state를 읽을 수 있음
- 자식에서 context를 받아 dispatch를 읽을 수 있음
- dispatch를 실행시키면 그 dispatch에 연결된 reducer가 실행되어 state가 변경됨
출처
https://react.vlpt.us/basic/22-context-dispatch.html