[#React-TypeScript), 'react-dom.development.js:16317 Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.'.]

calm·2022년 12월 14일
0

참고 :

https://wnsdufdl.tistory.com/245
https://bobbyhadz.com/blog/react-usestate-conditional-initial-value

1. 왜 이런 상황이 발생했을까요?

정의한 상태(state)가 무한(infinite) setState가 되고 있어, App이 StackOver된 상태

2. 무엇을 어떻게 해야할까요?

상태(state)를 setState 하고 있는 코드를 찾는다!

3. 관련한 코드는 무엇이었나요?

if (typeof localStoragePersitValue === 'string') {
    setPersist(JSON.parse(localStoragePersitValue) || false);
  }

4. 코드에 문제는 무엇이었나요??

setPersist(JSON.parse(localStoragePersitValue) || false);

localStorage에서 가져온 값을 state에 넣지않고, 그대로 setState함수(setPersist)에 할당 후 호출하고 있었습니다.

리액트는 상태(state)를 setState를 통해 새로운 상태로 변경(set)하고 이 변경사항을 적용(commit)합니다. 이후 컴포넌트의 리렌더링이 발생합니다.

해당 과정이 계속 발생되어(=함수호출이 되고 있어) stackover 상태를 갖게 됐습니다.

5. 어떻게 해결했나요?(=어떤 코드로 변경했나요?)

: 기존 setState에 넣었던 코드를 setState의 초깃값으로 정의했습니다.

 let localStoragePersitValue = localStorage.getItem('persist');

  const [auth, setAuth] = useState<ContextAuthType['auth']>(ContextInitialValue);
    
  const [persist, setPersist] = useState<ContextAuthType['persist']>(() => {
    if (typeof localStoragePersitValue === 'string') {
      const InitialLocalStorageValue =
        JSON.parse(localStoragePersitValue) || false;
      return InitialLocalStorageValue;
    }
  });

let localStoragePersitValue = localStorage.getItem('persist');
if (typeof localStoragePersitValue === 'string') {
const InitialLocalStorageValue = JSON.parse(localStoragePersitValue) || false;
return InitialLocalStorageValue;
}

Before : setState에 인자로 입력

if (typeof localStoragePersitValue === 'string') {
setPersist(JSON.parse(localStoragePersitValue) || false);
}

After : useState의 초깃값으로 변경

useState<ContextAuthType['persist']>(() => {
if (typeof localStoragePersitValue === 'string') {
const InitialLocalStorageValue =
JSON.parse(localStoragePersitValue) || false;
return InitialLocalStorageValue;
}
});

6. 앞으로 무엇을 염두하면 좋을까요?

setState()를 바로 호출하지 않도록 조심!

번외

 let localStoragePersitValue = localStorage.getItem('persist');

  const [auth, setAuth] = useState<ContextAuthType['auth']>(ContextInitialValue);
    
  const [persist, setPersist] = useState<ContextAuthType['persist']>(() => {
    if (typeof localStoragePersitValue === 'string') {
      const InitialLocalStorageValue =
        JSON.parse(localStoragePersitValue) || false;
      return InitialLocalStorageValue;
    }
  });

1. 타입스크립트에서 localStorage값이 null이 될 수 있어, null이 아닐 경우(=타입가드)에 작동해야 함으로 if{}문이 필요합니다

2. 훅(useState)은 조건문(if문) 안에 정의할 수 없어, 함수형태(()=>{})로 state를 정의했습니다

profile
공부한 내용을 기록합니다

0개의 댓글