React Context

2023. 1. 4. 20:31프로그래밍/React

    목차

React Context

리액트에서 데이터 흐름을 컨트롤하는 방법 중 하나 (상태 관리)
컴포넌트 트리의 깊이에 상관 없이 props를 전달하지 않고도 컴포넌트에 데이터를 제공함
전역 데이터를 관리하는 데 사용됨 (전역 상태, 테마, 서비스, 사용자 설정 ...)

React.createContext

const MyContext = React.createContext(defaultValue);
Context 객체를 생성함
생성된 Context 객체는 리액트가 관찰하는 구성 요소를 렌더링 할 때
트리에서 그 위에 가장 근접하게 일치하는 Provider에서 현재 컨텍스트 값을 읽음

defaultValue 인수는 트리에서 구성 요소 위에 일치하는 Provider가 없을 경우에만 사용됨

컨텍스트를 사용하려면 Provider로 컨텍스트를 사용할 컴포넌트를 감싸주어야 함


Context.Provider

<MyContext.Provider value={}>
  <AComponent />
  <BComponent />
  <CComponent />
</MyContext.Provider>
모든 Context 객체에는 Consumer Component가 컨텍스트 변경 사항을 구독할 수 있도록 하는
Provider React 구성 요소가 함께 제공됨
Context value에 변경 사항이 생길 경우 구독중인 컴포넌트가 리렌더링 됨 (A, B, C)
변경 사항은 Object.is 와 동일한 알고리즘을 사용하여 새로운 값과 이전 값을 비교해 결정됨

 

const MyContext = React.createContext({ userName: "John" });
<MyContext.Provider value={{ userName: "Han" }}>

만약 createContext 로 컨텍스트 생성 시

defaultValue 를 { userName: "John" } 이라고 전달했어도

Context.Provider value props에서 { userName: "Han" } 이라고 전달하면

두 번째 value가 Consumer Component 들에 전달됨

(Provider 를 이용해 Context 의 value 변경 가능)


Class.contextType

클래스형 컴포넌트에서 context value 를 사용하기 위한 속성
클래스의 contextType 속성에는 createContext() 로 생성된 Context 객체가 할당될 수 있음

contextType 속성 사용 시 this.context를 사용하여 해당 컨텍스트 유형의 가장 가까운 현재 value 사용 가능

렌더링 기능을 포함한 모든 생명 주기 메서드에서 해당 값 참조 가능

import React from 'react';

class MyClass extends React.Component {
  componentDidMount() {
    let value = this.context;
  }
  componentDidUpdate() {
    let value = this.context;
  }
  componentWillUnmount() {
    let value = this.context;
  }
  render() {
    let value = this.context;
  }
}

let MyContext = React.createContext("there");
MyClass.contextType = MyContext;

export default MyClass;

useContext

함수형 컴포넌트에서 context value 를 사용하기 위한 Hook
Context 객체를 인수로 전달받아 현재 Context value를 반환함
현재 Context value는 트리에서 호출 구성 요소 위에 가장 가까운 Provider의 value prop에 의해 결정됨

컴포넌트 위의 가장 가까운 <MyContext.Provider>가 업데이트 되면

이 Hook은 해당 MyContext Provider에게 전달된 최신 Context value로 다시 렌더링을 트리거함

const value = useContext(MyContext);

 

import React from 'react';

const themes = {
  light: {
    foreground: '#000000',
    background: '#eeeeee',
  },
  dark: {
    foreground: '#ffffff',
    background: '#222222',
  },
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <div className='App'>
      <ThemeContext.Provider value={themes.dark}>
        <Toolbar />
      </ThemeContext.Provider>
    </div>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = React.useContext(ThemeContext);
  return (
    <button style={{ backgroundColor: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

export default App;
  1. createContext API 를 이용해 Context 생성
  2. context value를 공유할 컴포넌트를 Context.Provider 로 감싸주고
    공유할 value를 value props로 전달
  3. 해당 컴포넌트에서 context value를 사용하기 위해 useContext Hook 사용
  4. 만약 Provider로 감싸주지 않으면 useContext로 반환한 값에는 초기 Context 생성 시 전달한 값이 들어있게 됨