본문 바로가기

main/React

[React] Context API, 전역 상태 관리하기, 두 개 이상의 Context 사용하기

유저의 정보나 헤더 등

전체 페이지에서 상탯값을 사용해야하는 요소들을 관리하기 위해

ContextAPI를 사용해보았다.

 

먼저 폴더구조는 다음과 같다.

1. createContext

먼저 context를 만든다.

 

Header.context.js에 헤더의 context를 만듦

import { createContext } from "react";

// 관리할 state 정의
const HeaderContext = createContext({
  view: false
});

export default HeaderContext;

 

2. Provider

state를 모아두는 provider를 만든다.

state와 setState 동작을 정의한다.

createContext를 받아와서 Provider로 return한다.

 

provider/HeaderProvider.component.js

import React, { useState } from "react";
import HeaderContext from "../Header.context";

const HeaderProvider = ({ children }) => {
  // 타 컴포넌트에서 사용할 함수
  const toggle = () => {
    setHeaderState(prevState => {
      return {
        ...prevState,
        view: !prevState.view
      }
    })
  };

  // state 초기화
  const initialState = {
    view: false,
    toggle
  };

  const [headerState, setHeaderState] = useState(initialState);
  
  return (
    <HeaderContext.Provider value={headerState}>{children}</HeaderContext.Provider>
  )
};

export default HeaderProvider;

 

3. useContext() 사용

- 가장 상위인 App.js에 먼저 Provider를 가져온다.

import HeaderProvider from "Context/provider/HeaderProvider.component";

return (
    <Container>
      <Router>
        <HeaderProvider>
        
          <HeaderComponent />
          <SideTabComponent />
          <Content isMobile={isMobile}>
            ...
          </Content>
          <FooterComponent />
          
        </HeaderProvider>
      </Router>
    </Container>
  );
}

 

- 사용할 컴포넌트에서 호출한다. state값 조회와 setstate수행할 toggle 함수 사용.

import HeaderContext from "Context/Header.context";

export default function HeaderComponent() {
  const { toggle, view } = useContext(HeaderContext);
  
  // view 값 조회
  console.log(view);
  
  return (
    // toggle 함수 사용
    <Header onClick={toggle}>
    ...

 

이제 전역에서 Header 관련 함수를 사용할 수 있게 됐다. !!

User Context 코드도 첨부해 두겠다.

`User.context.js`

import { createContext } from 'react';

const userContext = createContext({
  userInfo: {}
});

export default userContext;
`UserProvider.component.js`

import React, { useEffect, useState } from "react";
import UserContext from "../User.context";
import Axios from "axios";

const UserProvider = ({ children }) => {
  useEffect(() => {
    Axios.post(
      ...
      setUserInfo(response.data);
    })
  }, []);

  const [userInfo, setUserInfo] = useState({});

  return (
    <UserContext.Provider value={userInfo}>{children}</UserContext.Provider>
  )
};

export default UserProvider;

그런데 User context도 만들었으니 app.js에 추가해줘야되고, 앞으로도 context가 또 생길지도 모르는데..

여러 context를 사용하려면 app.js에 context 지옥이 생기는 걸까...

하다 검색해보니 여러 context를 사용할 수 있는 방법이 있었다.

 

App.js

export default function App() {
    const AppProvider = ({ contexts, children }) => contexts.reduce(
        (prev, context) => React.createElement(context, {
          children: prev
        }),
        children
      )

      return (
        <Container>
          <Router>
            <AppProvider contexts={[HeaderProvider, UserProvider]}>
              ...

깔끔하고 좋은데~