input type="checkbox"
를 버튼 형태로 렌더링한 영역을 클릭했을 때 다음과 같은 에러가 발생:
⇒ React는 처음에는 uncontrolled로 보이는데 나중에 값이 생기면서 갑자기 controlled로 바뀌니 혼란스러운 상황이라고 경고를 날리고 있는 것입니다.
React는 폼 요소(input
, textarea
, select
등)가 처음 렌더링될 때부터 제어 방식이 일관되어야 한다는 원칙을 가지고 있습니다.
React에서는 <input>
같은 폼 요소를 두가지 방식으로 관리합니다.
타입 | 설명 | 예시 |
---|---|---|
Uncontrolled (비제어) | 리액트가 값을 직접 관리하지 않고, DOM 자체에 값 저장 | <input defaultValue="hi" /> |
Controlled (제어) | 리액트 상태(state)로 값을 제어 | <input value={someState} onChange={...} /> |
const [watch, setWatch] = useState({
checked: {},
startDate: '',
endDate: '',
comment: '',
}
<form onSubmit={handleSubmit}>
{formField.map((field, idx) => (
<FormControl key={idx} label={field.label} inputType={field.type}>
{field.type === 'buttonsCheck' &&
field.options.map((option, i) => {
return (
<span key={i}>
<Button
styleType={selected ? 'brandSolid' : ''}
text={option}
onClick={e => {
e.preventDefault();
handleCheckbox(field.label, option);
}}
/>
<input
type="checkbox"
name={field.label}
id={`${field.label}-${option}`}
value={option}
checked={checked[field.label]?.includes(option,);}
onChange={() => handleCheckbox(field.label, option)}
/>
</span>
);
})}
</FormControl>
))}
</form>
현재 코드에서는checked[field.label]
가 초기에 undefined
상태로 비제어(Uncontrolled) 로 인식하였는데 나중에 값이 생기면 제어(Control) 상태로 바뀌게 되어 경고 발생한 것입니다.
checked[field.label]
의 값이 undefined
이더라도 안전하게 처리될 수 있도록 빈 배열로 기본값을 설정해주었습니다.
<input
type="checkbox"
name={field.label}
id={`${field.label}-${option}`}
value={option}
checked={(checked[field.label] || [])?.includes(option);}
onChange={() => handleCheckbox(field.label, option)}
/>