在设计React 组件的时候,必定要注意数据来源,确保每个数据都只有一个数据源。好比一个 state
不能既受 setState
的改变,又受 props
的变化而变化(好比componentWillReceiveProps
或是 getDerivedStateFromProps
中)。html
一旦遇到多数据来源的状况,请将其按照如下方案进行从新设计。react
getDerivedStateFromProps
的做用:数组
state
只受到props
的影响;- 只有当
state
与prop
不一样时,才去修改state
;
受控组件是指 state 彻底受Prop控制的组件。一般,建议将组件设计成彻底受控组件。ide
const ControlComponent = (props) => {
reutrn (<div>{ props.name }</div>)
}
// 或者
class ControlComponent extends React.Component {
state = {
name: 'xxx'
}
// 使用了 getDerivedStateFromProps 类更新的state,最好不要在组件中再使用
// setState 来修改了,要保证数据来源的惟一性。
staric getDerivedStateFromProps(nextProps, preState) {
return {name: nextProps.name}
}
}
复制代码
这个组件就是一个彻底受控组件,它没有自身的状态,彻底随着props改变而改变。this
非受控组价是指组件存在 state,且state仅保存在这个组件内部,受组件内部的 setState
改变,不受 props
影响。spa
class NoncontrolComponent extends React.Component {
state = {
name: 'inside'
}
change = () => {
this.setState({name: 'newName'})
}
render() {
const { name } = this.state
return (<button onClick={this.change}>{name}</button>)
}
}
复制代码
咱们知道key
是用来标识一个组件的。React
会根据 key
判断数组中的哪些元素改变了,哪些元素被新增删除了。若是数组中某个key消失了,React会认为这个元素被删除了,从而进行响应的操做。设计
因此根据这个特性,咱们能够给一个非受控组件设置一个动态的 key
。当须要重置(?应该是从新构建)这个非受控组件的时候,咱们能够直接改变 key
值就行了。code
这个key能够是有意义的,也能够是随机生成的。component
若是不给非受控组件设置key,但仍想重置/改变组件,咱们能够经过在组件中设置一个额外的标识符来达到相同的目的。htm
class NoncontrolComponent extends React.Component {
state = {
name: this.props.name,
id: this.props.id
}
static getDerivedStateFromProps(props, state) {
if (props.id !== state) {
return {
name: props.name,
id: props.id
}
}
return null // return null 表示不对 state 作改变
}
}
复制代码
此外,咱们还能够在组件中建立一个重置state
的的方法,而后让父组件经过 ref
来调用该方法以达到改变组件状态的目的。
class NoncontrolComponent extends React.Component {
state = {
name: 'xxx'
}
reset = name => {
this.setState({ name })
}
....
}
// 父组件使用 this.refs.component.reset() 就能够改变组件状态了
复制代码