React Context

seul gi lee·2020년 9월 19일
0

React

목록 보기
9/9
post-thumbnail

Context?

context를 이용하면 단계마다 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있습니다.

리액트에서는 부모 컴포넌트와 자식 컴포넌트간에 데이터를 전달할 수 있는데, 데이터를 전달할 때 부모에서 자식에게로만 데이터가 전달이 가능하다.
이러한 단방향 데이터 흐름에서 부모-자식간의 교류가 아닌 컴포넌트간의 데이터 교류. 즉 자식간의 교류가 필요한 경우 글로벌 상태 관리를 하기 위해 상태 관리 라이브러리가 등장!

그래서 리액트의 context를 사용하여 props를 넘겨주지 않고 컴포넌트 간의 값을 공유할 수 있다.

props vs context

  • props를 이용한 데이터 흐름
// Button 컴포넌트에서 theme 데이터를 쓰는 경우 - props로 넘겨주기

// App.js
class App extends React.Component {
  render() {
    return <Toolbar theme="dark" />;
  }
}

// Toolbar.js
// 중간 컴포넌트가 데이터를 넘겨줘야 한다.
function Toolbar(props) {
  return (
    <div>
      <ThemedButton theme={props.theme} />
    </div>
  );
}

// Button.js
class ThemedButton extends React.Component {
  render() {
    return <Button theme={this.props.theme} />;
  }
}
  • context를 이용한 데이터 흐름
// context api를 사용하여 Button 컴포넌트에서 전역상태 사용하기
const ThemeContext = React.createContext('light');

// App.js
class App extends React.Component {
  render() {
    // Provider를 이용해 하위 트리에 테마 값을 보내줍니다.
    // 아무리 깊숙히 있어도, 모든 컴포넌트가 이 값을 읽을 수 있습니다.
    // 아래 예시에서는 dark를 현재 선택된 테마 값으로 보내고 있습니다.
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}

// Toolbar.js
// 중간 컴포넌트가 일일이 테마를 넘겨줄 필요가 없다.
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

// Button.js
class ThemedButton extends React.Component {
  // 현재 선택된 테마 값을 읽기 위해 contextType을 지정합니다.
  // React는 가장 가까이 있는 테마 Provider를 찾아 그 값을 사용할 것입니다.
  // 이 예시에서 현재 선택된 테마는 dark입니다.
  static contextType = ThemeContext;

  function onThemeChange() {
    dispatch({
      type: 'COLOR_CHANGE',
      payload: ,'white'
    })
  }

  render() {
    return <Button theme={this.context} onClick = {this.onThemeChange} />;
  }
}
  • context api를 사용하면 컴포넌트의 재사용이 어렵다.
    ⇒ 재사용이 어려운 경우에는 리액트에서 컴포넌트 합성을 추천한다.

사용 시 주의사항

컴포넌트가 다시 렌더링할지 여부를 결정할 때 참조를 확인하기 때문에, provider의 부모가 렌더링 될 때마다 불필요하게 하위 컴포넌트가 다시 렌더링 되는 문제가 생길 수도 있다! 예를 들어 아래 코드는 value가 바뀔 때마다 매번 새로운 객체가 생성되므로 Provider가 렌더링 될 때마다 그 하위에서 구독하고 있는 컴포넌트 모두가 다시 렌더링 될 것이다.

class App extends React.Component {
  render() {
    return (
      <MyContext.Provider value={{something: 'something'}}>
        <Toolbar />
      </MyContext.Provider>
    );
  }
}

이를 피하기 위해서는 값을 부모의 state로 끌어올려야한다.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      value: {something: 'something'},
    };
  }

  render() {
    return (
      <Provider value={this.state.value}>
        <Toolbar />
      </Provider>
    );
  }
}

참고 - https://ko.reactjs.org/docs/context.html#gatsby-focus-wrapper

profile
백설 집사의 개발블로그입니다. :D

0개의 댓글