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값으로 사용)
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.