[React] useState의 굴레 (부제 : 난 그저 toggle button을 만들고 싶었을 뿐인데)

권이온·2022년 12월 5일
0

문제 발생

동아리 부원 모집 활성화 / 비활성화를 toggle button을 통해서 편하게 조정할 수 있도록 만들고 싶었다.

우선 동아리 모집이 활성화 되어있는 상태를 받아와서 true / false에 따라 다른 값을 렌더링 시켜야 한다.

그래서 if 문을 통해 해당 상태 데이터가 !undefined 임을 확인하고 그 안에서 이런 식으로 만들어 주었다.

그런데

Uncaught Error: Rendered more hooks than during the previous render.

에러가 떴다.

그래서 if 문 바깥에

const [RecruitIsOpen, setRecruitIsOpen] = useState(true);

를 선언해주고

const RecruitState~ 위에 setRecruitIsOpen(data1.opened)를 적어주었다.

그랬더니

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

에러가 떴다.

해결 시도

구글링 해보니 가장 유명한 해결방법은
https://stackoverflow.com/questions/55265604/uncaught-invariant-violation-too-many-re-renders-react-limits-the-number-of-re

화살표 함수를 이용하라는 것이었다. (비단 stackoverflow에만 이런 답변이 있지 않았다.)

하지만 난 이미 화살표 함수를 쓰고 있다고 생각하는데 어떻게 해야하나라는 생각이 들었다.

RecruitState 내부 Button 태그에서 onClick하지 말고 RecruitState 자체에 onClick을 줘봤지만 여전히 같은 에러가 발생했다.

<RecruitState onClick={() => {setRecruitIsOpen((e) => !e)}}/>

통째로 if 문 밖으로 빼도 같은 에러가 발생했다.

일단은 return 부분은 삼항 연산자로 넣어주었다.
화살표 함수를 쓰라는 것의 의미를 알게 되었는데 setState를 onClick일 때만 바뀌게 하라는 것이다. 하지만 난 초기값을 넣어주어야 하는데...

초기값은

const [RecruitIsOpen, setRecruitIsOpen] = useState(data1.opened);

이렇게 넣었는데 처음 몇 번은 잘 작동하더니

Uncaught Error: Rendered more hooks than during the previous render.

이 에러가 발생했다...

난 useState의 초기값에 data1.opened의 값을 넣고 싶은데 그걸 특정한 action(ex: onClick()을 통한 화살표 함수 이용) 없이는 계속 에러를 뿜을 것이 분명했다.

data1.opened의 값을 && 같은 것을 이용해서 특정 컴포넌트를 보이게 할까 생각도 했지만 곰곰히 생각해보면 안 될 것이 분명했다.

해결방법

4시간 정도 고민하니 새벽 2시가 넘어 일단 자야겠다고 생각해서 누웠는데 바로 해결 방법이 떠올랐다.

그냥 data1.opened의 값에 따라 useState의 초기값이 true인 것과 false 인 거 2개를 만들어서 넣어주면 되는 거였다.

느낀 점

쉽게 해결할 수 있는 것을 빙 돌아온 느낌이지만 덕분에 react-hook (useState, useEffect)에 대한 공부를 할 수 있는 시간이 되었다.

공식 문서도 읽어보고!
https://reactjs.org/docs/hooks-rules.html

useState는 비동기적으로 작동하기 때문에 setState()의 값이 즉시 업데이트가 되지 않을 수 있다.

profile
인생은 아름다워

0개의 댓글