useEffect에서 deps에 빈배열 []을 넣은 상태라, 현재는 컴포넌트가 렌더링 될 때 한 번만 userEffect실행된다.
[]를 생략하면 해당 컴포턴트가 렌더링 될 때마다 useEffect가 실행된다.
이 경우, 댓글 추가와 함께 동시에 업데이트 되지만, useEffect 가 계속 실행되면서 서버에서 댓글 목록을 계속 반환 받게 된다.
useEffect(()=> {
fetch('/api/comment/list?id=' + props._id, {method: "GET"}).then(r=>r.json())
.then((result)=>{
setData(result)})
}, []) // []을 없애면 계속 업데이트 된다.
deps의 빈배열 []을 삭제한뒤, console.log(result) 코드를 기재하는 순간, 개발자도구에 콘솔 로그 결과가 급속도로 반복 찍히는 것을 확인할 수 있었다. 불필요하게 계속 렌더링이 되면서, 서버에서 데이터 조회도 반복되는 것이다. 이것은 비효율적인 방법이여서 대안을 찾았다.
시도2 : deps 위치에 data 기재
let [data, setData] = useState([])
useEffect(()=> {
fetch('/api/comment/list?id=' + props._id, {method: "GET"}).then(r=>r.json())
.then((result)=>{
setData(result)}) // data 상태를 바꾸는 setData() 실행
}, [data]) // data가 변경되면 useEffect 실행
dependency배열에 data를 넣었다. 댓글 목록인 data가 변경될 때만 렌더링 되는 것을 기대했다.
하지만 콘솔로그가 시도1과 같이 무한으로 찍히는 것으로 보아, 잘못된 것을 인지했다.
- (1)댓글 목록인 data 상태가 바뀔 때 useEffect 내부 함수가 다시 실행되게 의도했는데, 이로인한 문제가 있다.
- (2) useEffect내부에서 setData(result)의 'data'상태를 바꾸는 setData함수를 다시 호출한다. 이 때문에 무한루프에 빠지게 만든 상태이다.
시도3 : useState 로 댓글 작성 후 댓글목록 리프레시 기능 추가
콘솔 로그가 두 번찍힌다. Next.js는 SSR 서버사이드 렌더링 이여서, 서버에서 미리 페이지를 렌더링하고, 클라이언트에 동적 부분을 다시 렌더링 하는 과정에서 콘솔 로그가 두 번찍힐 수 있다고 한다.
23.09.12 추가
리액트는 strict mode모드가 있어서 개발과정에서 어떤 문제를 찾기 위해 엄격하게 관리할 수 있다고 한다.
이전에는 마지막 시도를 통해 문제를 해결했지만, 동일한 현상이 생겼을 때 지금은 3번째 시도로 처리하려고 한다. 이유는 시도4번째 방법보다 더 편리하기 때문이다. 시도4는 이 문제를 이해하고 해결한 게 아니라고 생각한다.
useState(0)으로 생성하고, useEffect 내의 함수를 작동할 때 마다 useState()의 기존 값에서 +1 씩 증가하게했더니 리프레시 없이 비동기적으로 작동한다. useState()초기값을 null에서 하고, 즉 useState(null)에서 useState(true) 값으로 바꾸어도 잘 작동한다.
댓글