React.js + Next.js

React에서 "Uncontrolled to Controlled" 경고 해결하기

진호우 2024. 10. 22. 17:53

React로 폼이나 입력 컴포넌트를 만들다 보면 다음과 같은 경고를 접할 수 있다.

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.

 

이 경고는 React에서 컨트롤된 컴포넌트비컨트롤된 컴포넌트의 차이로 인해 발생하는 것이다. 이번 글에서는 이 경고의 의미와 해결 방법에 대해 알아보자.

 


 

1. 컨트롤된 컴포넌트 vs 비컨트롤된 컴포넌트

먼저 컨트롤된 컴포넌트와 비컨트롤된 컴포넌트의 차이를 이해해야 한다.

 

* 컨트롤된 컴포넌트: 컴포넌트의 상태(state)가 React에 의해 완전히 제어되는 컴포넌트이다. valuechecked 같은 속성을 명시적으로 설정하고, 이 값이 컴포넌트 상태와 동기화된다.

<input type="text" value={inputValue} onChange={handleChange} />

 

* 비컨트롤된 컴포넌트: React 외부에서 컴포넌트의 값을 제어한다. 즉, DOM이 스스로 관리하는 컴포넌트이다.

<input type="text" defaultValue="초기값" />

 

이 두 개념이 혼용되면 경고가 발생한다. 특히 처음에는 비컨트롤된 상태(undefined나 null)였다가, 이후에 컨트롤된 상태로 변경될 때 React는 경고를 발생시킨다.

 


2. 문제 상황: "Uncontrolled to Controlled" 경고

이 경고는 주로 SwitchInput, input, checkbox 등에서 발생할 수 있다. 예를 들어, 아래와 같은 코드에서 경고가 발생할 수 있다.

<input checked={data.isChecked} onChange={handleIsChecked} />

 

여기서 data.isChecked 가 처음 렌더링될 때 undefined일 경우, React는 이 input을 비컨트롤된 컴포넌트로 간주한다. 하지만 이후에 값이 true나 false로 변경되면, React는 이 컴포넌트를 컨트롤된 컴포넌트로 인식하면서 경고를 표시한다.

 


3. 해결 방법: 기본값 제공

이 문제를 해결하려면 checked 값이 undefined일 때 기본값을 제공해서 항상 컨트롤된 상태로 유지해야 한다.

수정된 코드

<input checked={data.isChecked ?? false} onChange={handleIsChecked} />

 

위 코드에서 data?.isChecked ?? false는 isChecked 값이 undefined일 때 false를 기본값으로 설정하는 것이다. 이를 통해 checked 값이 항상 boolean으로 유지되면서 경고가 사라지게 된다.

 


4. 정리

React의 입력 요소에서 "Uncontrolled to Controlled" 경고는 처음에 비컨트롤된 상태로 시작했다가 이후에 컨트롤된 상태로 변경될 때 발생한다. 이를 방지하기 위해서는 초기 상태에서 기본값을 제공하여 컴포넌트를 항상 컨트롤된 상태로 유지해야 한다.

 

?? 연산자를 사용하여 undefined일 경우 기본값을 설정하는 것이 유용하다.

React에서 경고 메시지를 관리하고 깔끔한 코드를 유지하기 위해서는 이러한 컨트롤 여부를 명확히 하는 것이 중요하다.