인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

dohyun_lim님의 프로필 이미지
dohyun_lim

작성한 질문수

[리액트 2부] 고급 주제와 훅

[2.1장 컨택스트] 2.1.4 공급자와 소비자

[2.1장 컨택스트] 2.1.4 공급자와 소비자 / 에서 질문이 있습니다.

해결된 질문

작성

·

306

1

안녕하세요 선생님 react context를 이해하려고 시도하는 중입니다.

const countContext = MyReact.createContext({
  count: 0,
  setCount: () => {},
});

class CountProvider extends React.Component {
  constructor(props) {
    console.log("CountProvider construtor");
    super(props);
    this.state = {
      count: 0,
    };
  }

  render() {
    const value = {
      count: this.state.count,
      setCount: (nextValue) => this.setState({ count: nextValue }),
    };
    return (
      <countContext.Provider value={value}>
        {this.props.children}
      </countContext.Provider>
    );
  }
}

const Count = () => {
  return (
    <countContext.Consumer>
      {(value) => {
        console.log("CountComponent", value);
        return <div>{value.count}</div>;
      }}
    </countContext.Consumer>
  );
};

const PlusButton = () => {
  return (
    <countContext.Consumer>
      {(value) => {
        console.log("PlustButtonComponent", value);
        return (
          <button onClick={() => value.setCount(value.count + 1)}>
            + 카운트 올리기
          </button>
        );
      }}
    </countContext.Consumer>
  );
};

export default () => (
  <CountProvider>
    <Count />
    <PlusButton />
  </CountProvider>
);

Count , Plus Button component return 문에 각각

console.log("CountComponent", value);
console.log("PlustButtonComponent", value);

로그를 남겨봤습니다.

사진에 표시 된 것 처럼 로그가 각 Component마다 2번씩 찍히는데 그 이유를 알 수 있을까요...?

로그의 value 값이 다른게 힌트 같은데 해석을 하지 못하겠습니다.

답변 2

1

김정환님의 프로필 이미지
김정환
지식공유자

MyReact를 구현하면서 생긴 부작용입니다.

  • Provider#render()가 children을 렌더할 때 Consumer가 렌더링되는데 이때 createContext()로 넣은 값을 사용합니다.

  • Provider#componentDidMount()가 실행될 때 value인자로 Consumer가 두 번째 렌더됩니다.

  •  

MyReact는 컨택스트 동작을 이해할 목적이라 참고만 해주세요. React 컨택스트와 비교해 보시는게 더 정확합니다.

실제 리액트의 컨택스트는 1번만 컴포넌트를 렌더하는데요. createContext(value)에 지정한 값을 렌더할 때마다 사용하지 않고요. Provider 없이 Consumer로 컨택스트에 접근할 경우 fallback 값으로 사용합니다.

 

질문 내용을 보고 답을 찾느라 시간이 좀 오래 걸렸습니다. 많이 기다리셨을텐데 죄송합니다.

0

안녕하세요, 인프런 AI 인턴입니다. dohyun_lim님, React Context API를 사용하여 상태 관리와 관련된 질문 주셨군요.

제시해 주신 코드와 이미지 기반의 설명으로, 로그가 각 컴포넌트마다 두 번씩 찍히는 현상은 React의 엄격 모드(strict mode)에서 개발 중일 때 생길 수 있는 일반적인 현상으로 보입니다. 개발 모드에서 React는 엄격 모드가 활성화되어 있을 때 부수 효과를 찾아내기 위해 컴포넌트의 마운트, 업데이트 및 언마운트를 두 번씩 실행합니다.

하지만 이러한 부분은 프로덕션 빌드에서는 발생하지 않으며, 정확한 원인 파악을 위해서는 실제 코드를 실행하여 React 개발자 도구의 엄격 모드 설정을 확인하거나, console.log 출력 위치의 컴포넌트 라이프사이클 메서드를 점검해보는 것이 필요합니다.

이미지의 설명에 따르면 개발 환경에서 React DevTools의 “Profiler”와 “Components”를 사용 중인 것으로 나타나므로 이 도구들을 활용해서도 추가적인 디버깅이 가능할 수 있습니다.

로그의 value 값이 다른 부분에 대해서는, 컴포넌트가 리렌더링될 때마다 새로운 객체 또는 함수가 생성되고 있을 가능성이 있습니다. 이는 CountProvider 컴포넌트의 render 메서드 안에서 매번 새로운 value 객체가 생성되기 때문에 발생할 수 있습니다. 이 경우, 각 리렌더링에서 생성되는 새로운 객체는 이전 객체와 다른 참조를 가지게 되므로, Consumer 컴포넌트가 리렌더링 되게 되며 이로 인해 추가적인 로그가 출력될 수 있습니다.

이 같은 현상을 방지하기 위해서는 React의 useCallback, useMemo와 같은 훅을 사용하여 불필요한 리렌더링을 방지하는 최적화 작업을 할 수 있습니다.

더 자세한 정보나 도움이 필요하시다면, 질문 게시판이나 개발 커뮤니티에서 직접 문의하시는 것이 좋습니다.

dohyun_lim님의 프로필 이미지
dohyun_lim

작성한 질문수

질문하기