Context

Context를 사용하기 위해 뒤적뒤적 검색을 하면서 이해를 하는 데에 애를 먹었다.
이해를 한 후에 나 같은 주니어 개발자가 조금 더 쉽게 이해할 수 있도록 이 글을 최대한 쉽게 풀어 설명해본다.
쉽게 설명한다고 설명했는데 어려운 부분이 있으면 댓글주세요~
아마 천천히 읽어본다면 이해할 수 있을 거라고 생각한다.

Context를 사용하는 이유

React에서 데이터는 부모 컴포넌트에서 자식 컴포넌트에게 단방향으로 props를 통해 전달된다. 컴포넌트가 늘어날수록 props를 통해 전해주는 과정은 번거로워진다.

Context는 트리 단계마다 명시적으로 props를 넘겨주지 않아도 많은 컴포넌트에서 값을 공유할 수 있도록 해준다.

React 컴포넌트 트리 안에서 전역적(Global)으로 데이터를 공유할 때 사용하면 좋다.

Context를 사용방법

  1. Context 생성 - createContext()
  2. Context 제공 - <Context.Provider value={{ ... }}>
  3. Context 사용 - <Context.Consumer>, useContext()

Context 생성

Context를 사용하기 위해서는 아래처럼 일단 createContext로 Context를 만들어준다.

const NewContext = createContext(/* defaultValue */);

Context를 만들면 Context 안에 Provider를 통해서 value를 지정해줘야 한다.

쉽게 설명하면 value에 전역적으로 사용할 값들을 넣어주면 된다.

Context 제공

이렇게 value를 설정하였다면 이제 Global로 사용할 컴포넌트를 감싸주면 된다.

<NewContext.Provider
	value={{
		변수,
		함수,
		상태,
		...
	}}
>
	<App />
</NewContext.Provider>

직접적으로 useState로 상태를 Global로 사용할 수도 있고, 또 useReducer란 Hook을 사용하여 상태를 관리할 수도 있다.

useReducer는 쉽게 설명하면 state의 관리를 좀 더 디테일하게 관리할 수 있는 useState의 대체 함수라고 생각하면 된다.

다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우나 이전 상태에 의존적인 경우에 useState보다 useReducer를 사용하는 게 좋다.

간단한 앱이나 복잡하지 않은 상태를 관리할 때는 useReducer보다 useState를 사용하는 것이 더 효과적일 수 있다.

useReducer는 다음과 같이 사용한다.

const [ state, dispatch ] = useReducer(reducer, initialState);

newState의 형태로 reducer를 받고 dispatch 함수와 짝의 형태로 현재 state를 반환한다.

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

위의 코드는 React 공식 문서의 코드이다.

어떤 식으로 사용하는지 코드를 보고 감을 잡으면 좋을 것 같아 참조한다.

dispatch 함수를 통해 action을 보낸다. 그럼 reducer 함수에 따라 상태를 변환한다.

위의 코드를 useReducer가 아닌 useState를 사용하면 아래와 같다.

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

Context 사용

위의 과정들을 거쳐서 Provider를 통해 value를 제공했으면 이제 받아서 사용하기만 하면 된다.

<Context.Consumer>

사용하기 위해서는 Consumer를 사용할 수 있다.

<NewContext.Consumer>
	{value => /* context 값을 이용한 렌더링 */}
</NewContext.Provider>

Context.Consumer의 자식은 반드시 함수여야 한다.

Provider의 value props가 없으면 createContext()에 사용한 defaultValue의 값이 할당된다.

useContext()

또 다른 방법으로는 useContext()를 사용하는 것이다.

const value = useContext(NewContext);
/* or */
const { 변수, 함수, 상태, ... (직접적으로 선언) } = useContext(NewContext);

Global로 사용할 값들을 useContext를 통해 선언하여 사용하면 된다.

물론 사용할 컴포넌트에서 선언해줘야한다.

참고자료

React 공식 문서

profile
끈기있고 꾸준하게!!

0개의 댓글