개발자
안녕하세요. 소켓 통신을 사용한 채팅 기능 구현중인 주니어 개발자입니다. 아래와 같은 상황에 보통 어떻게 대처하시나요? 문제: useEffect 사용 시 서버에 채팅 방 말풍선 목록을 요청(publish)하고, 요청한 데이터를 state 에 저장하는 과정에서 loop 가 생겨 useEffect 가 끊임없이 돌고 있습니다. 문제 설명: - 서버에 채팅 방 말풍선 목록을 요청할 때 넘기는 값 중에 direction 이라는 변수가 있는데요, 이 direction 변수는 채팅 방 말풍선 개수에 의존적입니다. 따라서 useEffect 의 dependency에 채팅 방 말풍선 목록이 들어가게 됩니다. - 서버로부터 데이터를 받은 즉시 채팅방 말풍선 목록을 state에 저장하게 됩니다. - 위 두 상황(useEffect의 deps 설정, setState) 때문에 loop 가 생기게 됩니다. 생각해본 해결 방안: - useRef 를 사용하여 deps 에 등록하지 않아도 최신 데이터를 바라볼 수 있습니다. - 말풍선 목록이 배열 데이터이기 때문에, 새로운 배열을 만들지 않고 기존 배열을 계속 사용하여 같은 메모리를 사용합니다. 같은 메모리를 사용하고 있기 때문에 useEffect 의 deps 에 등록하지 않아도 최신 데이터를 바라볼 수 있습니다. - 말풍선 목록을 링크드리스드 자료구조를 사용하고, 한 번 생성한 자료구조를 새로 만들지 않고 재사용하여 같은 메모리를 이용합니다. 같은 메모리를 사용하고 있기 때문에 useEffect 의 deps 에 등록하지 않아도 최신 데이터를 바라볼 수 있습니다. 위 해결 방안의 문제점: - useEffect 의 deps 에 등록하지 않는 방법은 anti pattern 이라는 느낌을 받습니다. 아마도 위 방법을 사용한 데이터를 사용하는 컴포넌트의 re-rendering 이 되지 않기 때문에 이런 느낌을 받는 것 같습니다. 참고 자료: [react 문서](https://react.dev/learn/removing-effect-dependencies#are-you-reading-some-state-to-calculate-the-next-state)
답변 2
소스코드를 봐야 정확할것 같은데 useEffect는 한개 이상 만들 수 있습니다. 안에서 첫로딩할때와 값이 변경될시 리로드가 하나의 useEffect에 몰려있으면 보통 무한루프에 잘 걸립니다. 생명주기 루틴을 잘 이해하셔야 되는데 보통 첫로딩때 값이 변경되는데 값이 변경되는 시점에 리로딩까지 걸어 놓았을 경우도 무한루프에 걸립니다. 이상황일 경우 useEffect를 분리하거나 둘중에 하나를 빼시거나 해야 될 겁니다.
우선 useEffect의 dependency에 들어간 '채팅 방 말풍선 목록'이 배열 데이터라 하셨는데 dependency로 배열이 들어가면 useEffect는 해당 데이터가 이전 데이터와 동일한지 구분하지 못 하기 때문에 항상 호출됩니다. dependency에 넣은 의미가 없어지죠. 아예 useEffect의 dependency에 넣지 않는다는 방법으로 'direction' 변수가 바뀐 경우 원하는 대로 호출이 잘 되나요? 원하시는 동작이 컴포넌트 마운트시 한번 호출이라면 괜찮겠지만 dependency가 없다면 useEffect는 한번 밖에 호출되지 않습니다. useEffect에서 호출하는 pub List에서 실제로 사용하는 값인 'direction' 변수가 원시 타입이라면 해당 값을 dependency에 넣어주는 것도 방법입니다. 이 값이 'set 말풍선 목록'을 하면서 바뀌지 않는다면 useEffect가 다시 호출 되지도 없을 것입니다. 그리고 useEffect로 호출한 값을 다시 dependency에 넣어 주는 것은 좋은 방법이 아니라고 생각됩니다. loop에 걸릴 수 밖에 없는 구조로 보이네요. 'pub List'와 'set 말풍선 목록'이 왜 그런 의존성을 갖게 되었는지 컴포넌트를 분리할 수는 없는지 확인해보는 것도 좋을 것 같습니다.
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!