共计 1703 个字符,预计需要花费 5 分钟才能阅读完成。
在 react 中,批改状态如果间接应用 this.state,不会引起组件的从新渲染,须要通过 this.setState 来对组件的属性进行批改。
1、this.setState 的两种定义形式
定义初始状态
state = {count: 0},
如果此时有一个按钮,点击按钮让计数加 1,咱们能够有两种写法
(1) 传递对象
this.setState({count: this.state.count + 1})
(2) 传递函数
this.setState((state, props) => ({count: count + 1}))
2、setState 的两种形式有什么不同?
如果变更的 state 的值须要依赖于上一次的 state 的值,这种状况就须要用到函数的模式,比方以下这种状况
addCount(){this.setState({ count: this.state.count + 1})
this.setState({count: this.state.count + 1})
this.setState({count: this.state.count + 1})
}
此时只会执行一次 + 1 的操作,因为在 React 外部,会将屡次 setState 合并操作,新的 state 由 Object.assgin({},{count: 0}, {count: 1}) 合并所得,以上赋值会执行三次,但因为 count 的值没有更新,所以最终执行的后果只 +1,如果 setState 的赋值是函数,那状况就不一样了
addCount(){this.setState((state, props) => ({count: count + 1}))
this.setState((state, props) => ({count: count + 1}))
this.setState((state, props) => ({count: count + 1}))
}
这样的操作会失去 + 3 的成果,因为 React 会进行判断,如果传入的是函数,那么将执行此函数,此时 count 的值就曾经被批改了
3、setState 是同步还是异步的?
☆☆☆☆☆ 是异步的
(1) 即咱们通过 this.setState 批改了状态之后,在它的下一行输入 state 的值并不会失去新的值
(2) 为什么是异步?
有两个起因,一是提高效率,每次批改 state 的值都会造成 render 的从新渲染,将屡次批改 state 的值合并对立更新能够进步性能;二是 render 的更新会晚一些,如果 render 中有子组件,子组件的 props 依赖于父组件的 state,props 和 state 就不能保持一致
(3) 如何获取异步时的 state 值?
① 在 setState 的回调函数中
this.setState({count: this.state.count + 1}},
()=>{ console.log(this.state.count)})
② 在 componentDidUpdate 中获取
componentDidUpdate(){console.log(this.state.count)
}
☆☆☆☆☆ 是同步的
(1) 即咱们通过 this.setState 批改状态之后,在它的下一行输入 state 是新的值
(2) 什么场景下是同步的?
① 原生 js 获取 dom 元素,并绑定事件
<button id="addBtn"> 点我 +1</button>
componentDidMount(){const addBtn = document.getElementById('addBtn')
changeBtn.addEventListener('click',()=>{this.setState({ count: this.state.count + 1})
console.log(this.state.message)
})
}
② 计时器 setTimeout
<button onClick={e => this.addOne() }> 点我 +1</button>
addOne(){setTimeout(()=>{this.setState({ count: this.state.count + 1})
console.log(this.state.count) },0)
}