非受控组件
在大多数情况下,推荐使用受控组件来处理表单数据。在一个受控组件中,表单数据是由React组件来管理的。另一种代替方案是使用非受控组件,这时候表单数据将交给DOM节点来处理。
要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数。你可以使用ref来从DOM节点中选取表单数据。 例如,下面的代码使用非受控组件接收一个表单的值:
class NameForm extends React.Component {
constructor(props){
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.input = React.createRef();
}
handleSubmit (){
alert('a name was submit :'+ this.input.current.value)
event.preventDefault();
}
render (){
return (
<form onSubmit = { this.handleSubmit }>
<label htmlFor="name"> Name: </label>
<input type="text" ref={this.input} />
<input type="submit" value="submit" />
</form>
)
}
}
ReactDOM.render(<NameForm /> , document.querySelector('#root'))因为非受控组件将真实数据储存在DOM节点中,所以在使用非受控组件时,有时候反而更容易同时继承React和非React代码。如果你不介意代码的美观性,并且希望快速编写代码,使用非受控组件往往可以减少你的代码量。否则,你应该使用受控组件。
默认值
在React渲染生命周期时,表单元素上的value将会覆盖DOM节点中的值。在非受控组件中,你经常希望React能赋予组件一个初始值,但是不去控制后续的更新,这种情况你可以指定一个defaultValue属性,而不是value。
render (){
return (
<form onSubmit = { this.handleSubmit }>
<label htmlFor="name"> Name: </label>
<input type="text" ref={this.input} id="name" defaultValue="blob" />
<input type="submit" value="submit" />
</form>
)
}同样,<input type="checkbox"> 和 <input type="radio"> 支持 defaultChecked,<select> 和 <textarea> 支持 defaultValue。
文件输入
在HTML中,<input type="file" />可以让用户选择一个或多个文件上传到服务器,或者通过使用File API进行操作。
<input type="file" />在React中,<input type="file" />始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制。 使用FileAPI与文件进行交互:
class FileInput extends React.Component{
constructor(props){
super(props)
this.handleSubmit = this.handleSubmit.bind(this)
this.input = React.createRef();
}
handleSubmit (event){
event.preventDefault();
console.log(this.input.current.files[0])
}
render (){
return (
<form onSubmit = { this.handleSubmit }>
<label htmlFor="name"> Name: </label>
<input type="file" ref={this.input} id="name" />
<input type="submit" value="submit" />
</form>
)
}
}