
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
개발도중 만난 Warning ..⚠️
해당 경고 메세지는 비제어 컴포넌트와 제어 컴포넌트를 혼용해서 사용할 때 발생하는 문제다.🔥
즉, 초기 value가 undefined였다가 나중에 값이 설정되면서 제어 컴포넌트로 변경되는 경우 발생한다.
먼저 제어 컴포넌트(Controlled Component)와 비제어 컴포넌트(Uncontrolled Component)가 뭔지 알아보았다.
제어 컴포넌트는 React의 상태(state)를 통해 폼 요소의 값을 관리하는 방식이다.
즉, 입력값이 제어되며, 값이 변경될 때마다 React가 렌더링을 다시 수행한다.
import { useState } from "react";
function ControlledInput() {
const [text, setText] = useState("");
return (
<div>
<input
type="text"
value={text} // 상태 값으로 입력값을 제어
onChange={(e) => setText(e.target.value)} // 상태 업데이트
/>
<p>입력된 값: {text}</p>
</div>
);
}
export default ControlledInput;
✔️ value 속성은 text 상태값을 반영한다.
✔️ onChange 핸들러를 통해 사용자가 입력할 때마다 state를 업데이트한다.
✔️ React가 폼 요소의 값을 직접 제어한다.
비제어 컴포넌트는 React의 state를 사용하지 않고, DOM 자체에서 값을 직접 관리하는 방식이다.
즉, useRef를 사용하여 폼 요소에 접근하고 값을 가져온다.
import { useRef } from "react";
function UncontrolledInput() {
const inputRef = useRef(null);
const handleClick = () => {
alert(`입력된 값: ${inputRef.current.value}`);
};
return (
<div>
<input type="text" ref={inputRef} /> {/* ref를 사용하여 DOM 직접 접근 */}
<button onClick={handleClick}>값 확인</button>
</div>
);
}
export default UncontrolledInput;
✔️ ref를 사용하여 input 요소에 직접 접근한다
✔️ 버튼 클릭 시 ref.current.value를 가져와서 알림 창에 표시한다.
✔️ React의 상태를 사용하지 않으므로 불필요한 렌더링이 발생하지 않는다.
제어 컴포넌트는 state를 통해 값을 관리하고, 비제어 컴포넌트는 ref를 사용해 DOM에 직접 접근한다.
제어 컴포넌트는 입력 값이 변경될 때마다 렌더링이 발생하지만, 비제어 컴포넌트는 렌더링 없이 값을 유지할 수 있다.
동적인 UI, 입력 값 검증, 실시간 반응이 필요한 경우에는 제어 컴포넌트가 적합하고,
성능 최적화가 필요하거나 초기값 설정이 중요한 경우에는 비제어 컴포넌트가 유리하다.
경고가 발생했던 이유는 value가 처음에는 undefined여서 비제어 컴포넌트로 간주되었지만, 이후 setValue로 값이 설정되면서 제어 컴포넌트로 변경되었기 때문이다.
➡️ 따라서, 제어 컴포넌트로 사용할 경우 초기값을 undefined가 아닌 빈 문자열 ""로 설정하면 경고를 방지할 수 있다.
👉🏻 결론적으로, 제어 컴포넌트와 비제어 컴포넌트는 각각의 장단점이 있으므로 상황에 맞게 선택하고, 혼용해서 사용하는 것은 피하는 것이 좋다.