2019-11-03 TIL

2019-11-03

Redux Store State 변화 전파에 따른 재렌더 실험

의문

부모 컴포넌트와 자식 컴포넌트가 모두 connect를 이용해 Redux Store의 testData라는 똑같은 state를 참조하고 있을 때,

그 testData가 변하면 각 컴포넌트 특히 자식 컴포넌트는 중복으로 재렌더가 발생할까?

결론

순서대로 이렇게 재렌더가 진행된다

  1. testData state가 변하는 순간 이를 참조하고있는 부모 컴포넌트가 재렌더된다.
  2. 이에 따라 자식 컴포넌트가 재렌더 된다. (다만 testData의 새 값이 반영되어 있으므로 우려와 달리 불필요한 추가 재렌더는 없다.)

참고로, 만약 부모 컴포넌트가 testData를 props에 매핑해 참조하지 않았고 있다면 자식 컴포넌트만 재렌더된다.

실험

React Native에서, 부모와 자식 컴포넌트는 모두 함수형 컴포넌트로 실험했다. (memo 등의 처리를 하지 않으면 클래스 컴포넌트보다 재렌더가 빈번히 일어난다)

코드

부모 컴포넌트

const ParentComponent = props => {
  console.count("부모 컴포넌트 렌더 // ");

  return (
    <View style={{ flex: 1 }}>
      <ChildComponent />
      // <ChildComponent duplicateProp={props.testData} /> // 추가실험 케이스
    </View>
  );
};

function mapStateToProps(state) {
  return {
    testData: state.testData.testData
  };
}

export default connect(mapStateToProps)(ParentComponent);

자식 컴포넌트

import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { connect } from "react-redux";
import { changeTestState } from "../store/actions/clips";

const ChildComponent = props => {
  console.count("자식 컴포넌트 렌더::::");
  return (
    <View>
      <Text>자식1 {props.testData}</Text>
      <TouchableOpacity
        onPress={() => {
          props.changeTestState(1); // redux의 testData state를 1씩 증가
        }}
        style={{ borderWidth: 1 }} >
        <Text>상태변경</Text>
      </TouchableOpacity>
      // <Text>{props.duplicateProp}</Text> // 추가실험 케이스
    </View>
  );
};

const mapStateToProps = state => {
  return { testData: state.testData };
};

const mapDispatchToProps = dispatch => {
  return {
    changeTestState: data => {
      return dispatch(changeTestState(data));
    }
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);

콘솔 로그

부모 컴포넌트 렌더 // : 1 // 초기렌더
자식 컴포넌트 렌더::::: 1

부모 컴포넌트 렌더 // : 2 // 상태변화
자식 컴포넌트 렌더::::: 2

부모 컴포넌트 렌더 // : 3 // 상태변화
자식 컴포넌트 렌더::::: 3
...
추가실험 케이스
같은 결과가 나왔다.
부모와 자식이 모두 connect되어있고, 부모가 자식에게 그 redux 변수를 props로 내려주는 꼬인 상황. 역시나 부모가 재렌더될 때 변경된 값이 자식에게 이미 반영되므로 똑같은 결과가 나온 것으로 보인다.

Minchang Kim
Minchang Kim
웹/앱 개발자 김민창입니다! 좋은 하루 되세요!