2. FrontEnd/React / / 2024. 10. 11. 13:59

[ React ] useState 초기값 설정 에러

728x90

에러문구

Warning: A component is changing a controlled input to be uncontrolled.
This is likely caused by the value changing from a defined to undefined, 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

이 에러는 “Controlled input이 Uncontrolled로 바뀌었다”는 경고

이는 컴포넌트가 처음에는 입력 필드에 값을 제어하다가 나중에는 값이 undefined 또는 null로 설정되어 React가 더 이상 그 필드를 제어하지 않는 상태가 되면서 발생하는 문제이다.

Controlled vs Uncontrolled Components:

Controlled Component: valueonChange를 통해 React 상태로 입력 필드를 제어하는 방식입니다.
즉, 입력 필드의 값을 useState로 관리하는 경우가 이에 해당

Uncontrolled Component: 입력 필드의 값을 React 상태로 관리하지 않고, DOM 자체에서 값을 관리하는 방식입니다.
예를 들어, defaultValue를 사용하는 방식

 

에러 원인

초기 상태값이 undefined로 설정됨: useState로 설정한 값이 초기 렌더링 시 undefined로 설정되어 있거나, value 값이 동적으로 undefined가 되는 경우

입력 필드에 null 또는 undefined가 전달됨: 예를 들어, TextFieldvalue가 빈 상태여야 하지만, undefinednull로 전달되어 발생할 수 있다. React는 value에 빈 문자열("")을 기대하지만, null이나 undefined가 넘어가면 경고가 발생함

 

에러 해결방법

1. 초기값 설정: useState로 관리하는 상태의 초기값을 명확하게 설정하세요. 만약 값이 없으면 빈 문자열을 기본값으로 설정

//전코드
const [username, setUsername] = useState(user?.username);
const [year, setYear] = useState(userYear);
const [month, setMonth] = useState(userMonth);
const [day, setDay] = useState(userDay);

//후코드
const [username, setUsername] = useState(user?.username || '');
const [year, setYear] = useState(userYear || '');
const [month, setMonth] = useState(userMonth || '');
const [day, setDay] = useState(userDay || '');

2. 값이 없을 때 빈 문자열 사용: value 속성에 undefinednull이 전달되지 않도록, 값이 없을 때는 빈 문자열을 전달

//전코드
<TextField
  fullWidth
  required
  className="maxWidth600"
  name="name"
  size="small"
  placeholder="이름을 입력해주세요."
  value={username}
  onChange={handleUsername}
/>

//후코드
<TextField
  fullWidth
  required
  className="maxWidth600"
  name="name"
  size="small"
  placeholder="이름을 입력해주세요."
  value={username || ''} // undefined일 경우 빈 문자열로 처리
  onChange={handleUsername}
/>

 

3. 상태 초기화 시 주의: useEffect에서 상태를 초기화할 때도 마찬가지로 undefinednull을 빈 문자열로 처리

//전코드
  // user가 업데이트되면 year, month, day, username, companyName 등의 상태를 다시 초기화
  // useEffect를 통해 user 데이터가 변경될 때 상태를 다시 설정
  useEffect(() => {
    if (user) {
      const birth = user?.birth?.split('-');
      setYear(birth?.[0]);
      setMonth(birth?.[1]);
      setDay(birth?.[2]);
      setUsername(user?.username);
      setCompanyName(user?.companyName);
    }
  }, [user]);

//후코드
useEffect(() => {
  if (user) {
    const birth = user?.birth?.split('-') || ['', '', ''];
    setYear(birth[0]);
    setMonth(birth[1]);
    setDay(birth[2]);
    setUsername(user.username || ''); // user.username이 undefined일 경우 빈 문자열로 설정
    setCompanyName(user.companyName || '');
  }
}, [user]);

 

요약

 

에러가 발생하는 이유는 input 필드가 처음에 제어되고 있다가 이후 undefined 값을 받아 비제어 컴포넌트로 변경되기 때문

이를 해결하려면 상태의 초기값을 빈 문자열로 설정하거나, valueundefined 또는 null일 경우 빈 문자열을 대신 전달하는 방법을 사용해야함

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유