Context

Jinmin Kim·2021년 4월 5일
0

Context

Context의 기초 개념

프로퍼티와 state는 부모와 자식 컴포넌트가 연결된 상태에서 공유하는 데이터였는데, 컨택스트는 부모와 자식 컴포넌트가 연결되어있지 않아도 데이터를 공유할수있게 만들어준다.

보통 컴포넌트는 아래 왼쪽 그림의 구조와 같은 트리 구조를 가지고있다.
아래와 같은 구조에서는 a라는 데이터를 프로퍼티로 넘겨주기위해서는
A -> B -> C -> D를 거쳐야 데이터를 넘길수가있게된다.
근데 만약 React에서 a데이터를 넘겨주다가, 전달과정에서 누락되거나 사용되지않아서
React app에서 error가 날수있다. 데이터를 어떻게 하면 직접 전달해줄수 있지 않을까 해서
나온 방법이 관잘자 패턴을 도입하는것이었다.

오른쪽의 그림은 A 데이터를 D로 넘겨주기위해서 A가 공급자로 a를 보내게되면
소비자가 공급자를 구독하고 있다가 그 데이터를 받아서 사용할수있도록 D로 넘겨주게된다.
이를 컴포넌트간의 자료 의존성이 사라졌다라고 이야기하고 이러한 기술을 컨텍스트라고 이야기한다. 소비자는 하이어오더 컴포넌트 이다.

공급자와 소비자 관계

  • 소비자는 공급자보다 낮은 계층에 있어야한다
  • 소비자는 공급자가 제공하는 콜백함수로 데이터를 변경할수있다.
    소비자도 공급자의 데이터를 변경할수있지만, 소비자가 공급자의 데이터를 변경할때는
    공급자의 데이터에 직접 접근하여 변경하는것이 아니라 공급자로부터 데이터 변경을 위한 콜백함수를 받아 데이터 변경 요청을 하여야한다. 이러한 단방향 데이터 흐름은 데이터의
    일관성을 유지하는데 매우 효과적.

공급자

공급자를 구현하는 방법은 공급자의 자료형, 데이터 제공 함수를 정의하면된다.

//데이터 제공 함수 ex)
  getChildContext() {
    return {
      loading: this.state.loading,
      setLoading: this.setLoading,
    };
  }
//공급자의 자료형 ex)
HomePageComponent.childContextTypes = {
  loading: PropTypes.bool,
  setLoading: PropTypes.func,
};

공급자의 데이터가 state로 관리된다고 생각할때, loading 데이터를 setLoading()를 가지고
소비자가 데이터 변경 요청을 할때 사용하는 콜백요청이다. 소비자에서 setState() 함수를 호출하여 공급자의 state를 변경한다.

컴포넌트 공급자 분리

컴포넌트에서 공급자를 분리한다. 분리된 공급자 컴포넌트는 PureComponent가 아닌
Component 클래스를 사용한다. PureComponent는 컨텍스트 변경에 대한 비교가 생략되어있기때문

소비자 구현(하이어오더 컴포넌트로)

  • 소비자의 역활을 할 컴포넌트에 contextTypes 속성을 추가하여 공급자에서 구독할 항목 정의(모든 컴포넌트에 contextTypes 속성을 추가하긴 불편하므로 하이어오더 컴포넌트 개념 도입)
export const loadingPropTypes = {
  loading: PropTypes.bool,
  setLoading: PropTypes.func,
};

//컨택스트로 전달받은 객체를 프로퍼티로 변환하여 전달
function WithLoadingContext(props, context) {
    const { loading, setLoading } = context; //컨택스트 구조 분해
    return <WrappedComponent {...props} loading={loading} setLoading={setLoading} />;
  }
  
//구독할 컨텍스트의 항목을 정의한 contextTypes를 추가  
WithLoadingContext.contextTypes = loadingPropTypes;

컨텍스트 사용

컨텍스트 API

위의 것들은 Context API를 이해하기 위함이며, 위의 내용들은 컨텍스트 API에 들어갔다.
createContext로 Context를 만들수있다.

const MyContext = React.createContext(defaultValue)
//1. MyContext.Provider, MyContext.Consumer로 접근하여 사용
//2. const {Provider, Consumer} = React.creatContext(defaultValue);
-> 분할 할당하여 사용

앞에서 공급자, 소비자를 구현할때 contextTypes, childContextTypes 속성을 일일이 정의했으나, 이제 API를 사용하면 알아서 관리해서 사용할수있게해준다.

import React from 'react';
const { Provider, Consumer } = React.createContext({});
// 공급자와 소비자를 생성
export { Consumer };

export default class LoadingProvider extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {};
    this.setLoading = this.setLoading.bind(this);
  }

  setLoading(key, value) {
    const newState = { [key]: value };
    this.setState(newState);
  }

  render() {
  //컨텍스트 데이터
    const context = {
      ...this.state,
      setLoading: this.setLoading,
    };
  //공급자의 컨텍스트 데이터 value 프로퍼티로 하위로 전달
    return <Provider value={context}>{this.props.children}</Provider>;
  }
}

컨텍스트 Modal

do it react 책을 정리한 내용입니다!!

profile
Let's do it developer

0개의 댓글