学前知识准备
props和state
props:props是从父组件那里继承的属性,自己组件内不可改变,只能在父组件进行修改,所以它是受父组件控制的。官方文档里描述“组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props”。所以props是个牵线木偶是个乖乖崽父组件说什么就是什么。
state:state是描述组件内的状态值,可以在组件内进行改变,每一次setState去改变state,会触发render()函数去重新渲染页面。注意不能直接进行赋值修改state。this.state.comment = 'Hello’这样写是错的。state是不随父组件变化而变化的,它是个逆子,有自己的想法,在组件内想修改就修改。
受控组件和非受控组件
注意:(广义上的受控与非受控组件的说法),React 组件的数据渲染是否被调用者传递的props完全控制,控制则为受控组件,否则为非受控组件。
非受控组件:React中写一个表单组件,如果可以使用ref来从DOM节点中获取表单数据,那就是个非受控组件。例子如下
import React, { Component } from 'react'
export default class MyInput extends Component {
myref = React.createRef() // 非受控组件将真实数据储存在 DOM 节点中,所以要创建一个ref去取到这个dom里的数据
render() {
return (
<div>
<input ref={this.myref} defaultValue="Bob"/>
<button onClick={this.handleSubmit}>提交</button>
</div>
)
}
handleSubmit = (event) => {
alert('A name was submitted: ' + this.myref.current.value);
event.preventDefault();
}
}
注意:
1)在 React 渲染生命周期时,表单元素上的 value
将会覆盖 DOM 节点中的值,在非受控组件中,你经常希望 React 能赋予组件一个初始值,但是不去控制后续的更新。 在这种情况下, 你可以指定一个 defaultValue
属性,而不是 value
。
2)在 React 中,<input type="file" />
始终是一个非受控组件,因为它的值只能由用户设置,而不能通过代码控制。
受控组件:React中写一个表单组件,如果完全是通过state去控制输入,即用户输入什么数据,就通过setState去更新相应的state数据。将上面例子改为受控组件,代码如下所示:
import React, { Component } from 'react'
export default class MyInput extends Component {
constructor(props){
super(props)
this.state={
value:'Bob'
}
}
render() {
return (
<div>
<input value={this.state.value} onChange={this.change}/>
<button onClick={this.handleSubmit}>提交</button>
</div>
)
}
change = (evt) =>{
this.setState({
value:evt.target.value
})
}
handleSubmit = (event) => {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
}
如上面的例子所示,表单里input里输入数据由state里的value字段去控制,每次输入都调用setState方法去修改state的value字段数据,提交弹出来的时候得到的结果是输入后变化的数据。