getSnapshotBeforeUpdate : render 메소드가 호출되고 실제로 DOM에 적용되기 직전에 불립니다. 그래서 DOM에 적용되기 직전에 상태를 기억했다가 DOM에 적용된 직후에 무언가 조절을 해줄 것이 있다면, getSnapshotBeforeUpdate
와 componentDidUpdate
를 이용하면 됩니다.
기존에는 이런 역할을 하는 곳에서 props를 받아다가 state를 조절해 줄 수 있었습니다. 그런데 이제는 아예 대놓고 그 일만 하는 훅으로 바뀐것입니다.
return 부분에서 새로운 state를 설정해 줄 수 있습니다.
이전에는 props가 변경 됐을 때만 실행이 됐지만, 이후부터는 render가 실행되지 전에 거의 무조건 불린다고 보시면 되겠습니다.
nextProps와 관계 없이 State가 변경되도 불립니다.
예시
static getDerivedStateFromProps(nextProps, prevState) {
console.log("getDerivedStateFromProps", nextProps, prevState);
// 이 함수는 return이 있어야 합니다.
//아무것도 하지 않는다면 null을 반환해야 합니다.
return {// state의 age값을 새로 390으로 설정해줍니다.
age: 390,
};
}
getDerivedStateFromProps
는 매우 특수한 경우에만 쓰이게 됩니다. 보통 추천되는 방식은 시간의 흐름에 따라 변하는 Props에 State가 의존하는 경우
를 위해서 존재한다고 보면 됩니다.
예시 div가 세로로 새롭게 한개씩 쌓이면서 화면밖으로 나가게 되면 scrollbar도 같이 최신의 div를 쫓아서 가게 만드는 예제입니다.
//render 전의 스크롤 상태와 render 후의 스크롤 상태를 비교해서 맞춰주는 작업을 해야 합니다.
let i = 0;
class App extends React.Component {
state = { list: [] };
render() {
return (
<div id="list" style={{ height: 100, overflow: "scroll" }}>
{this.state.list.map((i) => {
return <div>{i}</div>;
})}
</div>
);
}
componentDidMount() {
setInterval(() => {
this.setState((state) => ({
list: [...state.list, i++]
}));
}, 1000);
}
getSnapshotBeforeUpdate(prevProps, prevState) {
if (prevState.list.length === this.state.list.length) return null;
const list = document.querySelector("#list"); // 여기서 dom api에 접근하는 것은 react에서 추천하는 방식은 아닙니다.
return list.scrollHeight - list.scrollTop;
}
// update 하기 전에 어딘가에 snapshot을 저장하겠다는 함수입니다. 그 저장되는 스냅샷이 이 함수의 return 입니다.
// return null; 을 해주는 아무것도 저장하지 않겠다는 의미입니다.
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(snapshot);
if (snapshot === null) return;
const list = document.querySelector("#list"); // 여기서 dom api에 접근하는 것은 react에서 추천하는 방식은 아닙니다.
list.scrollTop = list.scrollHeight - snapshot;
}
}
결과
위처럼 렌더 전 후의 상황을 연결해주는 일이 필요하다면 getSnapshotBeforeUpdate 를 사용하면 됩니다.
componentDidCatch
가 나오기 전까지는 react 앱으로 부분적으로 에러가 발생했을 때, 전체 웹사이트가 동작을 안하는 문제가 있었습니다. componentDidCatch 를 사용할 수 있게 되면서 에러시 에러 화면을 보여줄 수 있다거나 에러를 처리할 수 있게 되었습니다.
componentDidCatch 가 일어난 하위 컴포넌트에서 문제가 발생했을 때, 해당 부모 컴포넌트에서 문제가 발생한 것이 아닌 다른 것을 보여주는 기능입니다.
자기 자신에게 문제가 발생한 것은 catch를 할 수 없습니다. 그래서 우리가 만든 컴포넌트 중에 가장 최상위에 있어야 그 밑에서 발생한 에러를 잡아서 처리해 줄 수 있습니다.
에러 바운더리 docs : https://ko.reactjs.org/docs/error-boundaries.html