이 포스트는 React 공식문서의 Suspense 관련 부분을 보던중 아래의 내용을 실행해보기 위한 포스트 입니다.
Suspense를 사용하여 효율적으로 제어할 수 있는 race condition을 useEffect내에서도 처리하기 위한 방법입니다.
클로저, 스코프 체인와 cleanUp function을 이용하였습니다.
여기서 정의하는 경쟁상태란 코드가 실행되는 순서에 대한 부정확한 가정에서 비롯되는 버그 입니다.
위의 이미지는 useEffect 내에서 promise를 통해 데이터를 불러온후에
컴포넌트의 상태를 업데이트하는 동작 화면입니다.
promise의 응답 시간은 무작위로 설정되어 있습니다.
next 버튼을 클릭하면 id를 변경해주고 변경된 id로 각 컴포넌트에서 promise로 요청을 보내줍니다.
useEffect내에서 클로저, 스코프체인과 cleanUp Function을 이용한 버전입니다.
function ProfileTimeline({ id }) {
const [posts, setPosts] = useState(null);
useEffect(() => {
let status = true;
fetchPosts(id).then((p) => {
if (status) setPosts(p);
});
return () => {
status = false;
setPosts(null);
};
}, [id]);
// 생략
}
코드를 살펴보면
1. useEffect 내에서 status변수를 선언합니다.
2. fetchPost 즉 Promise를 실행시키고
3. 컴포넌트가 unMount될때 cleanUp function을 통하여 스코프내의 status를 false, posts를 null로 변경해줍니다.
만약 next를 연속으로 실행하여 id가 바뀌었고 promise가 실행된 컴포넌트가 unMount 되었다면
cleanUp function을 통해 status는 false로 재할당됩니다.
이후 useEffect내의 메소드는 실행컨텍스트가 소멸됩니다.
promise가 resolve를 통해 then을 실행하게 되면 then내의 함수는 status를 가지고 있지 않습니다.
이 함수가 선언된 위치를 기준으로 실행컨텍스트가 생성되고 실행컨텍스트의 스코프 체인을 통해 상위 스코프에 선언된 status에 접근을 할 수 있게 됩니다.
이때의 status는 false이므로 Posts의 업데이트는 실행되지 않습니다.
이러한 과정을 가진 코드가 많아진다면 코드는 지저분해질 수 있습니다.
깔끔하게 Suspense를 사용하면 해결할 수 있습니다.
Suspense를 사용하는 모습
Suspense가 안정된 버전으로 그리고 모든 라이브러리에서도 안정되게 제공해주고 타입스크립트도 적용이 완벽히 될수 있었으면 좋겠습니다.
출처: https://ko.reactjs.org/docs/concurrent-mode-suspense.html
'Frontend > React' 카테고리의 다른 글
React 재조정 🌱 (0) | 2022.04.15 |
---|---|
React hook 🌱 (0) | 2022.04.14 |
React suspense (1) | 2022.04.10 |
React 상태관리의 과거, 현재 그리고 미래 (번역글) (0) | 2022.04.09 |
Recoil 🌱 (0) | 2022.04.08 |