Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
두둥 유난히 긴 에러 등장!
이게 뭐지?
일단 이 에러가 어떻게 등장했냐면. . . 수정하기 버튼을 통해 열리는 모달이 open된 후 에러가 발생했다.
일단 무슨 에러인지 알아보자.
우선 controlled와 uncontrolled에 대해 살펴보자.
공식문서를 참조하여 정리해보자.
single source of truth로 만들어 두 엘리먼트를 결합할 수 있다. 그러면 폼을 렌더링하는 리액트 컴포넌트는 폼에 발생하는 유저 입력값을 제어하게 된다. *single source of truth : 모든 데이터 요소를 한 곳에서 제어하거나 편집하도록 조직하는 것⇒ React가 아닌 DOM에서 처리된다는 뜻!간단히 정리해보자.
제어 컴포넌트 → 사용자 액션에 따라 실시간으로 값이 필요할 때 사용
비제어 컴포넌트 → onSubmit과 같이 제출 시에 값이 필요할 때 사용
이제 어디서 에러가 시작됐는지 파헤쳐보자.
Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components
에러는 아래 코드에서 난 걸로 예상할 수 있었다.
<input type='text' className='form-control' value={data?.email} placeholder={t('text.enter.email')} readOnly={true} />
감이 온다. 바로 바꿔주자!

정리하자면, 모달 내의 input 태그에서 value에 undefined가 들어갈 수 있었던 것이었다. 리액트 입장에서는 초기값이 undefined일 수도 있기에 uncontrolled input이라고 인지하게 될 것이다.
하지만 유저 액션(onChange event-handler)에 따라 input이 바뀌게 되면서 controlled input으로 변경하려는 시도가 감지되어 위와 같은 에러가 뜨게 된 것이다!!
해결은 했지만 그래도 예의상 에러와 함께 띄워준 링크에 들어가보자.

그렇다고 한다.
If you provide a
valueto the component, it must remain a string throughout its lifetime.
제일 중요한 문장인 것 같다. 컴포넌트에 value를 활용한다면, 이건 리액트 생명주기 동안에는 무조건 string으로 존재해야 한다!
나와있는 솔루션을 보니 이미 잘 고친 듯 하다. ㅎㅎ