리액트 useEffect 를 사용중에 유저의 리뷰를 받을 수 있는 reviewWriter 컴포넌트에서 있었던 문제이다.
내가 구현하고자 했던 기능은 유저의 리뷰 내용이 변경됐을때 수정하기 버튼이 활성화되고 변경되지 않았다면 수정하기 버튼이 비활성화 되기를 원했다.
해당 컴포넌트의 동작 방식은
1. 서버 응답으로 Promise 를 받아 해당 유저의 리뷰가 있는지 확인 2. 리뷰가 있다면 해당 컴포넌트의 상태로 set 3. 해당 내용을 보여주고 수정사항이 감지되면 (deps) 변경점에 대한 rating과 text를 새로운 상태로 만듦 4. 수정하기 및 작성하기 버튼이 눌렸을 때 서버로 POST 요청을 날림
구현한 내용으론 isDirty(rating이나 text를 유저가 수정했다면 isDirty === true)
가 false 라면 수정하기 버튼을 비활성화하도록 조건을 달아놨다.
(1) 에서 isDirty
를 false
로 만들어주면 첫 마운트시점에서는 당연히 유저가 변경한 내용이 없을 것이기에 수정하기 버튼이 비활성화 되도록 만들려고 했으나,
(3) 에서 새로운 상태를 만들면서 isDirty
를 true
로 변경해주는 부분 때문에 setIsDirty(false) -> setIsDirty(true)
순서대로 작동을 하여 유저시점에선 무조건 컴포넌트 마운트 후에는 활성화된 수정하기 버튼이 보였다.
(1) 의 setIsDirty(false)
를 setTimeout(() => {}, 0)
으로 콜스택 맨 뒤 태스크로 보내서 해결.
근데 해당 타이밍문제에 의한 setTimeout은 사용은 문제가 없다고 생각했는데 혹시 더 좋은 방법이 있을지?