Post

Warning: A component is changing an uncontrolled input to be controlled.

⛔문제상황

input을 사용한 컴포넌트를 만들다 아래와 같은 오류가 발생했다.

app-index.js:35 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

🤔이유

값이 정의되지 않은 값에서 정의된 값으로 변경되어 발생한 문제일 수 있습니다.

에러 문구를 읽어보며 왜 이런 에러가 발생했는지 힌트를 얻을 수 있었는데, value 값을 넣으면서 발생한 오류로 보였다.

graph LR; A(useQuery로 데이터 불러오기) --> B(atom으로 관리); B--> C(useEffect에서 lang에 따라
defaultTranslate state 지정); C--> D(input의 value값으로 사용)

이런 흐름을 통해 input의 value값을 넣는데, react 컴포넌트가 마운트되기 전에, value의 초기값이나 이전값이 undefined였다가, 추 후에 실제 값으로 변경되기 때문이다.

❌기존 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
export default function MusicTranslateEdit({id, lang}: PropsType) {
  //recoil
  const music = useRecoilValue(musicAtom)

  //이미 작성되어 있는 가사 불러오기
  let [defaultTranslate, setDefaultTranslate] = useState<string[]>([])
  useEffect(() => {
    if (lang === "ko" && music.kotranslate) {
      let splitTranslate = music.kotranslate.split("\n")
      setDefaultTranslate(splitTranslate)
    } else if (lang === "jp" && music.jptranslate) {
      let splitTranslate = music.jptranslate.split("\n")
      setDefaultTranslate(splitTranslate)
    }
  }, [music, lang])

  return (
    <input
      value={defaultTranslate[index]} 👈
      type="text"
      {...register(`lyrics_${index}`, { required: true })}
      id="title"
    />
  )
}

✅해결

초기값이 undefined가 아니면 되기 때문에 ""를 이용해 간단히 해결했다.

1
2
3
4
5
6
7
8
return (
  <input
    value={defaultTranslate[index] ? defaultTranslate[index] : ""} 👈
    type="text"
    {...register(`lyrics_${index}`, { required: true })}
    id="title"
  />
)
This post is licensed under CC BY 4.0 by the author.