Context

zmin·2022년 7월 19일
0

보통 전역 값의 사용은 지양하는게 좋지만
전역적으로 값이 관리 되어야 하는 경우가 생기기도 함
(로그인된 유저 정보, 다크/라이트모드 같은 테마 등등)

→ 이럴 때 기존의 props으로 값을 전달해주는 방식을 이용하다보면
A 에서 B로 값을 전달해주기위해 A→a→b→…→B 와같이 쓸데없이 많은 컴포넌트를 거치게 될 수도 있음

(위와 같이 테마를 전달해주는 경우는 실제 styled-componentsd의 ThemeProvider로 구현되어있음)

Context

const Custom = React.createContext(default)

Context 객체를 만들고 이를 전역 변수 관리에 이용할 수 있음
한 가지 유의해야할건 하나의 context는 하나의 value만 사용 가능
(default의 경우 provider를 찾지 못했을 때 사용 → 특별히 컴포넌트가 강제로 이동되거나 하는 것이 아니라면 거의 사용되지 않는다고 보면 됨)

하위 컴포넌트에게 값 뿌리기

전역으로 값을 사용하고 싶은 최상단 컴포넌트를 아래 태그로 감싸기

<Custom.Provider value={/*전역으로 사용하고 싶은 값(state..method..)*/}>
  <최상단컴포넌트 />
</Custom.Provider>

이제 하위 컴포넌트에서는 value property를 이용하여 전역 값을 관리할 수 있음
만약 상위 값을 변경하고 싶다면 이 value로 메소드를 넘겨주면 됨

  • value 값이 변경되면 이 context를 구독하는 컴포넌트 전부 리렌더링
    → 이때 여러개의 context를 사용하고 싶다면 여러 개의 provider를 중첩해서 사용 가능
  • 후손 컴포넌트 모두가 이 값을 읽을 수 있으며 만약 같은 context provider가 중첩되어 사용된 경우 위쪽 방향으로 가장 가까이 있는 값 사용
  • 다음처럼 여러 개의 context를 이용할 수 있음
    const ThemeContext = React.createContext('light');
    const UserContext = React.createContext({ user: 'unknown' });

    class App extends React.Component{ 
        render() {
            ...
            return (
                <ThemeContext.Provider value={theme}>
                    <UserContext.Provider value={user}>
                        <자식컴포넌트/>
                    </UserContext.Provider>
                </ThemeContext.Provider>
            );
        }
    }

구독하기

  • 함수형 컴포넌트 - <Context.Consumer> 이용
  • 클래스형 컴포넌트 - 클래스의 contextType 프로퍼티에 아까 만든 context 객체를 대입해주면 해당 class 컴포넌트는 그 context를 구독하게 된다
    → 상위의 value를 바로 사용가능
    • 하지만 <Context.Consumer> 도 이용 가능하며 여러 개의 context를 구독하려면 이를 이용해야함
// 클래스형
class ChildComponent extends React.Component {...}
ChildComponent.contextType = Custom;

// 함수형 - 여러 개의 context를 구독하는 법은 다음과 같다
...
return (
  <Another.Consumer>
    { another => {
      <Custom.Consumer>
          { value => {/* 후손 컴포넌트 렌더링, value 이용 */} }
      </Custom.Consumer>
    }
  </Another.Consumer>
);

useContext (Hook)

함수형 컴포넌트에서 사용가능
위의 예시 중 Consumer 부분에서 각 <Context.Consumer>로 감싸던 것을 대체

값을 구독하고 싶은 컴포넌트에서 const globalValue = useContext(contextVariable);와 같이 선언하고 사용가능
-> 보기도 편하고 간편함


https://reactjs.org/docs/context.html

profile
308 Permanent Redirect

0개의 댓글