setState 成本比较高,每setState一次都会调用render渲染一次,setState会影响性能
如下面调用了四个setState,那么会render四次
import React,{ Component } from 'react';
class index extends Component {
constructor(props) {
//构造函数
super(props);
this.state = {
date: new Date(),
count01:0,
count02:10,
count03:100,
}
console.log("contructor-->",props)
};
tick=()=>{
console.log("tick->called")
this.setState({
date: new Date()
})
this.setState({
count01:this.state.count01++
})
this.setState({
count02:this.state.count02++
})
this.setState({
count03:this.state.count03++
})
}
componentDidMount(){
console.log("DidMount")
this.timer = setInterval(() =>{
this.tick()
},1000)
}
render() {
console.log("render-->",this.state)
const {date} = this.state;
return (
<h2>现在是:{date.toLocaleTimeString()}</h2>
);
}
}
export default index;
因为上面设置了定时器,每秒会执行一次tick(),红框中是执行一次tick()打印出来的
所以,为了提高组件性能,尽量一次把所有要改变的值放到同一个setState里面
import React,{ Component } from 'react';
class index extends Component {
constructor(props) {
//构造函数
super(props);
this.state = {
date: new Date(),
count01:0,
count02:10,
count03:100,
}
console.log("contructor-->",props)
};
tick=()=>{
console.log("tick->called")
this.setState({
date: new Date(),
count01:this.state.count01++,
count02:this.state.count02++,
count03:this.state.count03++
})
}
componentDidMount(){
console.log("DidMount")
this.timer = setInterval(() =>{
this.tick()
},1000)
}
render() {
console.log("render-->",this.state)
const {date} = this.state;
return (
<h2>现在是:{date.toLocaleTimeString()}</h2>
);
}
}
export default index;
这里需要注意的是,this.props 和this.state可能是一部更新的,不应该依靠它们的值来计算下一个状态。
例如上面的 count01:this.state.count01++,可能无法更新,要修复它,要使用第二种形态的setState()来接收一个函数而不是一个对象,该函数将接收先前的状态作为第一个参数(pre),将此次更新被应用时的props作为第二个参数(参数名可以自己设置)
this.setState((pre,props)=>({
date: new Date(),
count01:pre.count01 +1,
count02:pre.count02 +1,
count03:pre.count03 +1
}))
原本是写成
this.setState((pre,props)=>({
date: new Date(),
count01:pre.count01 ++,
count02:pre.count02 ++,
count03:pre.count03 ++
}))
因为++是先赋值再加,等于没变,所以 ++ 无效,所以换成了+1
另外要避免直接将props中的属性赋值给state中的属性
this.state = {
name = this.props.name //尽量避免使用这种方法,props改变时name 不会更新
}