React 16.4 getDerivedStateFromProps 적용기

문제 상황

레거시 코드에서 componentWillReceiveProps를 사용하고 있었는데, React 16.3부터 deprecated 경고가 뜨기 시작했다. 팀 내에서 React 16.4로 업그레이드하기로 결정하면서 본격적으로 대응이 필요했다.

기존 코드는 이런 형태였다.

componentWillReceiveProps(nextProps) {
  if (nextProps.userId !== this.props.userId) {
    this.setState({ loading: true });
    this.fetchUserData(nextProps.userId);
  }
}

getDerivedStateFromProps의 제약

getDerivedStateFromProps는 static 메서드라 this에 접근할 수 없다. 즉, setState 후 API 호출 같은 사이드 이펙트를 처리할 수 없다.

static getDerivedStateFromProps(nextProps, prevState) {
  // this.fetchUserData() 호출 불가능
  if (nextProps.userId !== prevState.prevUserId) {
    return {
      prevUserId: nextProps.userId,
      loading: true
    };
  }
  return null;
}

해결 방법

componentDidUpdate에서 사이드 이펙트를 처리하도록 분리했다.

static getDerivedStateFromProps(nextProps, prevState) {
  if (nextProps.userId !== prevState.prevUserId) {
    return {
      prevUserId: nextProps.userId,
      loading: true,
      data: null
    };
  }
  return null;
}

componentDidUpdate(prevProps, prevState) {
  if (this.props.userId !== prevProps.userId) {
    this.fetchUserData(this.props.userId);
  }
}

소회

React 팀이 왜 이런 설계를 했는지는 RFC 문서를 읽고 이해했다. 렌더링과 사이드 이펙트를 명확히 분리하려는 의도였다. 하지만 실무에서는 단순히 코드만 길어진 느낌이다. Hooks가 나오면 이런 문제가 해결될지 궁금하다.

React 16.4 getDerivedStateFromProps 적용기