대부분의 경우 폼을 구현하는데 제어 컴포넌트를 사용하는게 좋지만 제어 컴포넌트에서 폼 데이터는 React에서 다루어진다. 대안인 비제어 컴포넌트는 DOM자체에서 폼 데이터가 다루어진다.
비제어와 제어가 통합된 환경에서 사용한다.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.input = React.createRef();
}
handleSubmit(event) {
alert('A name was submitted: ' + this.input.current.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" ref={this.input} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
특정 상황에서 사용해야 하는 컴포넌트의 타입이 명확하지 않은 경우, https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/ 이걸 읽어보
React 폼 엘리먼트의 value 어트리뷰트는 DOM의 value를 대체한다. 비제어 컴포넌트를 사용하면 React의 초기값을 지정하지만, 그 이후의 업데이트는 제어하지 않는게 좋다. 이러한 경우에는 defaultValue
어트리뷰트를 사용하자. 컴포넌트가 마운트된 후에 defaultValue
를 변경해도 DOM의 값이 변경되지는 않는다.
또한 checkbox, radio는 defaultChecked
를 지원하고 select와 textarea는 defaultValue
를 지원한다.
파일 태그는 비제어 컴포넌트이기 때문에 ref를 걸어서 사용하자.
class FileInput extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.fileInput = React.createRef();
}
handleSubmit(event) {
event.preventDefault();
alert(
`Selected file - ${this.fileInput.current.files[0].name}`
);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Upload file:
<input type="file" ref={this.fileInput} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
}
const root = ReactDOM.createRoot(
document.getElementById('root')
);
root.render(<FileInput />);