setState
- 只要执行setState, 不管有咩有变化,都会render
- 更新时可能是异步更新也可能是同步更新
- 几个更新会被合并
- 自动进行浅合并
// 用于类组件,修改this.state中的值
constructor(props) {
super(props)
this.state = {
count: 0
}
}
// z在react的合成事件和生命周期(除了componentDidUpdate)中,setState是异步的,
// 在生命周期钩子调用中,更新策略都处于更新之前,组件仍处于事务流中,
// 而componentDidUpdate是在更新之后,此时组件已经不在事务流中了,因此则会同步执行;
// 在合成事件中,React 是基于 事务流完成的事件委托机制 实现,也是处于事务流中;
// 第一步: 处于 batchUpdate isBatchingUpdates = true
setState({
count: 1
}, ()=> {
// 返回更新的值
console.log(this.state.count) 1
})
// 上边的代码会自动浅合并成
setState({
...this.state,
count: 1
})
console.log('count:=', this.state.count) // 0
setTimeout(()=>{
// 第三步:此时isBatchingUpdates是false
this.setSate({
count: this.state.count + 1
})
console.log('count:=', this.state.count) // 1
}, 1000)
// 第二步 结束后, isBatchingUpdates = false
// 传入对象, 会被合并,执行结果只一次,渲染的值是 +1(类似于 object.assign({},{}))
this.setSate({
count: this.state.count + 1
})
this.setSate({
count: this.state.count + 1
})
this.setSate({
count: this.state.count + 1
})
console.log(this.state.count) // 1 在合并多个setState时,若出现同名属性,
// 会将后面的同名属性覆盖掉前面的同名属性
setTimeout(()=>{
this.setSate({
count: this.state.count + 1
})
this.setSate({
count: this.state.count + 1
})
},0)
console.log(this.state.count) // 2
// 在react的合成事件和生命周期中调用setState,React的性能优化机制会合并多个setState,
// 在原生事件、setTimeout中调用setState,是不受React管理的,所以不会合并,
// 写了几个setState执行几次
// 传入函数,不会被合并,执行结果是渲染的值是 +3
this.setState((preValue, props)=>{
return {
count: this.state.count + 1
}
})
this.setState((preValue, props)=>{
return {
count: this.state.count + 1
}
})
this.setState((preValue, props)=>{
return {
count: this.state.count + 1
}
})
useState
- 自定义名字
- 可以使用多个useState()
- 异步更新,用useEffect()进行监听
- 不具备浅合并的效果
const [count, setCount] = useState(0)
const [obj, setObj] = useState({})
setCount(1)
// 引用数据类型需要手动进行浅合并
setObj({
...obj,
name: 'zx'
})
useEffect(()=>{
console.log(count)
}, [count])