React.createContext

이승훈·2023년 2월 14일
1

TIL

목록 보기
23/32

props drilling을 방지하기 위한 react 자체 api 이다.
context를 사용하면 컴포넌트 트리 전체에 데이터를 제공할 수 있다.

context의 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것이다.
context를 사용하면 컴포넌트를 재사용하기가 어려워지니 꼭 필요할 때만 써야한다.

사용 방법

React.createContext

const MyContext = React.createContext(defaultValue);

context 객체를 만든다.
defaultValue 매개변수는 트리 안에서 적절한 Provider를 찾지 못했을 때만 쓰이는 값이다.
Provider를 통해 undefined를 보내도 구독 컴포넌트들은 undefined 를 읽고 defaultValue를 읽지 않는다.

Context.Provider

<MyContext.Provider value={/* 어떤 값 */}>

React.createContext를 통해 만들어진 context 객체에 포함된 React 컴포넌트인 Provider는 context를 구독하는 컴포넌트들에게 context의 변화를 알린다.

Provider 하위에서 context를 구독하는 모든 컴포넌트들은 Provider의 value prop이 바뀔 때 마다 새로 렌더링 된다.

Context.Consumer


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

context의 변화를 구독하는 React 컴포넌트이다.
Context.Consumer 컴포넌트는 함수 컴포넌트에서 context를 구독하기 위해 사용된다.

Context.Consumer 의 자식은 함수여야한다.
자식인 함수는 context의 현재값을 받고 React 노드를 반환한다.
이 자식놈의 함수가 받는 value가 Provider가 제공하는 value다.

상위에 Provider가 없다면 defaultValue다.

사용 예시

// createContext에 보내는 기본값의 모양을
// 하위 컴포넌트가 받고 있는 매개변수 모양과 동일하게 만드는 것 잊지마세요!
export const ThemeContext = React.createContext({
  theme: themes.dark,
  toggleTheme: () => {},
});
import {ThemeContext} from './theme-context';

function ThemeTogglerButton() {
  // ThemeTogglerButton는 context로부터
  // theme 값과 함께 toggleTheme 매서드도 받고 있습니다.
  return (
    <ThemeContext.Consumer>
      {({theme, toggleTheme}) => (
        <button
          onClick={toggleTheme}
          style={{backgroundColor: theme.background}}>
          Toggle Theme
        </button>
      )}
    </ThemeContext.Consumer>
  );
}

export default ThemeTogglerButton;

import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    // state에 업데이트 메서드도 포함되어있으므로
    // 이 또한 context Provider를 통해 전달될것입니다.
    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
  }

  render() {
    // Provider에 state 전체를 넘겨줍니다.
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}

function Content() {
  return (
    <div>
      <ThemeTogglerButton />
    </div>
  );
}

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
root.render(<App />);
profile
Beyond the wall

0개의 댓글