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가 나오면 이런 문제가 해결될지 궁금하다.