useContext 알아보기
useContext란?
useState는 데이터를 최상단 컴포넌트에서 생성한 후 props로 자식 컴포넌트에 계속 전달해야 한다.
이를 props drilling이라고 한다.
이를 해결하기 위해 등장한 것이 useContext다.
전역 상태 관리 도구는 아니지만, 특정 상태를 전역처럼 쉽게 공유할 수 있도록 도와준다.
createContext, useReducer, Provider 등을 활용해
1. context 폴더에서 상태를 관리하고
2. 필요한 컴포넌트에서 useContext를 통해 가져다 쓰면 된다.
context.js
크게 다섯 가지 단계로 나뉜다.
- 액션 정의
- 초기값 생성
- reducer 함수
- createContext
- Provider
01 액션 정의
액션은 상태를 변경할 조건을 정의한 객체다. 단순 문자열보다 한 곳에서 관리하기 편리하고, 오타 방지를 위해 정의해주는 것!
export const ACTIONS = {
INCREMENT: 'increment',
DECREMENT: 'decrement',
RESET: 'reset',
};
02 초기값 생성
상태의 초기값을 설정한다. 여러 개의 상태를 객체 형태로 관리할 수 있다.
const initialState = {
count: 0,
user: null,
};
03 reducer 함수
상태 변경 로직을 정의하는 핵심 함수다. state와 action을 받아 새로운 state를 반환한다.
useState에서 상태를 어떤 조건에서 어떻게 변경할건지 (주로 newData 등의 변수로 정의해줬던 로직)을 넣어서 하나의 액션으로 만들어주는 거다.
상황별 필요한 몇가지 액션을 만들어서 나중에 갖다 쓰기만 하면 되는 것!
function reducer(state, action) {
switch (action.type) {
case ACTIONS.INCREMENT:
return { ...state, count: state.count + 1 };
case ACTIONS.DECREMENT:
return { ...state, count: state.count - 1 };
case ACTIONS.RESET:
return { ...state, count: 0 };
default:
return state;
}
}
action은 type과 payload를 가진다.
type은 실행할 액션의 종류, payload는 액션 수행에 필요한 데이터
각 액션마다 필요한 payload가 다르기 때문에, 처음에 헷갈려서 꽤 고생했다..
액션을 정할때 옆에 주석으로 항상 payload가 뭔지 적어두는 걸 추천
04 createContext
import { createContext } from 'react';
export const CounterContext = createContext();
05 Provider
위에 만든 모든 걸 엮어서 Provider로 묶어준다.
import { useReducer } from 'react';
import { CounterContext } from './CounterContext';
export function CounterProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<CounterContext.Provider value={{ state, dispatch }}>
{children}
</CounterContext.Provider>
);
}
06 내보내기
export { CounterProvider, CounterContext, ACTIONS };
Provider, Context, 위에 정의해뒀던 액션들만 export하면 된다.
사용하기
01 세팅
context를 사용할 최상위 컴포넌트를(주로 App.jsx) Provider로 감싸준다.
import { CounterProvider } from './context/CounterContext';
function App() {
return (
<CounterProvider>
<MainComponent />
</CounterProvider>
);
}
02 사용하기
useContext를 사용하여 state와 dispatch를 가져온다. 이때 인자로는 내가 만들었던 컨텍스트를 넣어주면 된다.
dispatch({ type: '액션명', payload: '데이터' }) 형식으로 액션을 실행한다.
import { useContext } from 'react';
import { CounterContext, ACTIONS } from '../context/CounterContext';
function Counter() {
const { state, dispatch } = useContext(CounterContext);
return (
<div>
<p>카운트: {state.count}</p>
<button onClick={() => dispatch({ type: ACTIONS.INCREMENT })}>+1</button>
<button onClick={() => dispatch({ type: ACTIONS.DECREMENT })}>-1</button>
<button onClick={() => dispatch({ type: ACTIONS.RESET })}>초기화</button>
</div>
);
}
useState 쓰면서 정말 props 넘겨주고 받는게 너무 번거로웠는데
(특히 상태가 추가될 때마다 state, Setstate 이렇게 두개씩 넘겨주는 게 정말 지저분해 보여서 싫었다)
context를 사용하니까 훨씬 깔끔하고 쉽다. 좋은 거 알아간다~!
'WEB > react' 카테고리의 다른 글
[react/공부] useRef (0) | 2025.02.06 |
---|---|
[react/공부] styled-componenet (1) | 2025.02.05 |
[react/공부] CRA, Vite 없이 React 개발 환경 구축하기 (1) | 2025.02.04 |
[react/공부] useState로 컴포넌트 상속 알아보기 (0) | 2025.02.03 |
[react/공부] Hook이 뭐야? (0) | 2025.01.31 |