> Extra/Error Code

TIL-2024.07.12 - ERROR- 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.

Janku 2024. 7. 12. 12:03

 

 

 

 

 

 

 

 

 

배경

 

- Login 페이지에서 Email input Tag 에 onChange 될 때, onChangeIdInput 이 실행되어 setId 로 설정하려고 작업

- 아래의 코드와 같이 작성 후, 웹에서 id 입력할 떄, 아래 사진과 같은 에러 발생

const [id, setId] = useState();
const [password, setPassword] = useState();

const onChangeIdInput = (event) => {
     setId(event.target.value);
};

const onChangePasswordInput = (event) => {
     setPassword(event.target.value);
};

... 생략 ...

<label htmlFor="email">Email</label>
<input type="email" id="email" value={id} onChange={onChangeIdInput}/>

... 생략 ...

 

 

 

 


에러메시지

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

 

> 해석

경고: 컴포넌트가 비제어 입력 필드를 제어되는 입력 필드로 변경하고 있습니다. 이는 일반적으로 값이 undefined에서 정의된 값으로 변경되면 발생하는 문제입니다. 컴포넌트의 생명주기 동안 제어되는 입력 필드(controlled component) 또는 비제어 입력 필드(uncontrolled component) 중 하나를 선택하세요. 자세한 정보는 다음 링크를 참조하세요

 


원인

- React에서 초기 상태에 따라 입력 요소를 제어되는 상태(controlled)와 비제어 상태(uncontrolled)로 전환하려고 할 때 발생
   > 제어 상태 > 비제어 상태  혹은  비제어 상태 > 제어 상태 전환될때 발생되는 에러

 

- 이는 일관되게 관리하는 데이터 흐름을 예측 가능하게 유지하지 못할 수 있기에 발생된 에러

 

 

제어 상태 와 비제어 상태

1. 제어되는 상태(Controlled):

  • 상태 관리: 입력 값은 React의 상태(state)에 의해 제어.
  • 초기화: useState를 사용하여 초기 상태를 설정.
  • 값 바인딩: 입력 요소의 value 속성을 상태 변수에 바인딩.

예시

const [inputValue, setInputValue] = useState('');

const handleChange = (event) => {
    setInputValue(event.target.value);
};

return (
    <input
        type="text"
        value={inputValue}
        onChange={handleChange}
    />
);

 

 

 

2. 비제어 상태(Uncontrolled):

  • 상태 비관리: 입력 값은 DOM 자체에서 관리.
  • 초기화: 초기 상태를 설정하는 대신 defaultValue 속성을 사용합니다.
  • 값 바인딩: value 대신 defaultValue 속성을 사용합니다.

예시

return (
    <input
        type="text"
        defaultValue="초기 값"
    />
);

 


해결 방안

- 해결 방안은 생각보다 간단함.

- 가급적이면, 제어 상태에서 작업해주는게 좋음 (DOM 에서 값을 관리하는 것 보다)

 

방법 1. useState 에 초기값 설정해주기

const [id, setId] = useState('');
const [password, setPassword] = useState('');

 

 

방법 2. input Tag 의 value 에 빈 값 추가

<input type="email" id="email" value={id || ''} onChange={onChangeIdInput}/>