直接使用
this.state.counter = 5;
这种改变方式,虽然改变了致,但是react不知道他已经改变了,所以不会渲染,
setState是继承的,在Component的原型上
setState是异步更新的:
this.state = {
counter = 0
}
this.setState({
counter: 5
})
console.log(counter)//显示还是原来的counter 0
原因:
手下要承认的是 setState时re-render是很差的操作,重新渲染需要时间和资源
1.假设我们使用props传值给子组件, 如果父组件setState()同步更新了state时,父组件传给子组件的props是不会立即刷新的,因为无法同步re-render,就无法同步刷新props,这样自组建的props和父组件的state数据不一样了,破坏了内部数据的统一。
2.每次re-render会使用很多资源,效率很低,最好的办法就是同步获取多个更新,之后进行批量更新,
如何立即获取更新的数据呢?
1.在setState中添加回调函数
this.setState({
counter:5
},())=>{
console.log(counter)//5
}
2.生命周期函数 而且运行优先级高于setState的回调函数
ComponentDidUpdate(){
console.log(this.state.counter)//5
}
但有的时候setState是同步更新:
setState在合成事件(onClick)和钩子函数是异步的
在settimeout和原生事件,dom里是同步的
componentDidMount() {
document.getElementById("btn").addEventListener("click", () => {
this.setState({
message: "hello react"
})
console.log(this.state.message)
})
}
setTimeout(() => {
this.setState({
message:"hello react"
})
console.log(this.state.message)
},0)
数据的合并
this.state=({
counter: 0;
age: 18
)}
this.setState({
counter:1
)}
修改后 为什么age不会消失呢?
通过Object.assign实现的
Object.assign({}, this.state, {counter:1})
后面的属性会覆盖前面形同的属性
setState本身的合并
Component.prototype.setState = function(partialState, callback) {
//将这个组件, setState内的值,回调函数穿了过去
this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
enqueueSetState(inst, payload, callback) {
根据this拿到组件实例
const fiber = getInstance(inst);
const eventTime = requestEventTime();
//优先级
const lane = requestUpdateLane(fiber);
const update = createUpdate(eventTime, lane);
update.payload = payload;
enqueueUpdate(fiber, update);
通过enqueueUpdate将update存到updateQueue里面
}
getStateFromUpdate通过
// Merge the partial state and the previous state.
Object.assign({}, prevState, partialState);
合并之前的状态和现在
在
processUpdateQueue中通过 do while 每次里面都调用getStateFromUpdate
进行更新, 就导致 每次后面中更新的setState把之前setState里面的值覆盖
所以increment() {
//1.setState本身被合并 输出为1
/* this.setState({
counter: this.state.counter + 1
});
this.setState({
counter: this.state.counter + 2
});
this.setState({
counter: this.state.counter + 1
}); *}
//1.setState本身被合并 输出为最后一次的setState的操作 输出为2
this.setState({
counter: this.state.counter + 1
});
this.setState({
counter: this.state.counter + 1
});
this.setState({
counter: this.state.counter + 2
});
/* // 2.setState合并时进行累加,当输入为函数时会累加合并
因为在这个时候里面有一个判断,如果传过来的是函数 ,就。,执行这个函数call()中包括前一次的值
this.setState((prevState, props) => {
return {
counter: prevState.counter + 1
}
});
this.setState((prevState, props) => {
return {
counter: prevState.counter + 1
}
});
this.setState((prevState, props) => {
return {
counter: prevState.counter + 1
}
}); */
```