事件总线-setState用法和原理-diff算法和key
事件总线
注册一个 EventBus
发送自定义事件(emit)
arduinoeventBus.emit('click', 'why', 18, 1.88)
后面的参数就是需要传递的数据
监听并接收事件(on)
javascriptcomponentDidMount(){ eventBus.on('click', this.prevClick) } prevClick = (name, age, name) => { console.log(name, age, name) }
监听事件并接收传递过来的数据
移除监听事件(off)
javascriptcomponentWillUnmount(){ eventBus.off('click', this.prevClick) }
出于性能的考虑,组件销毁时需要移除事件的监听
setState用法和原理
为什么要使用 setState
开发中不能通过直接修改 state 的值来让界面发生更新, React 也没有实现 Vue 的数据劫持
必须通过 setState 来告知 React 数据发生了变化,根据最新的 State 渲染界面。
setState 的更多用法
setState 可以传入一个回调函数,回调函数的参数是之前的 state 和 props。好处在于:
- 可以在回调函数中编写新的 state 的逻辑
- 可以获取之前的 state 和 props
javascript
this.setState((state, props) => {
console.log(state, props)
return {
count: state.count + 1
}
})
setState 异步更新
setState 是异步操作:执行完 setState 后,不能立即得到更新后的 state。那么,如何获取异步更新后的结果?
setState
第二个参数传一个回调函数- 在生命周期函数
componentDidUpdate
里面写
React 18提出之后,setState 默认都是异步的。为什么 setState 是异步的?
- 因为可以显著提升性能。如果每次 setState 完都要进行一次更新,那么 render 函数将会频繁调用,导致频繁渲染界面。所以 setState 是批处理更新的(把更新的 state 都合并到更新队列,再一次更新。
- 如果同步更新了state,但是还没有执行 render 函数,那么 state 和 props 不能保持同步(会出现 state更新但 props 还未更新的情况;
如果要强制同步应用特定的 state 更新,这时可以将其包装在 flushSync
中,但这可能会损害性能。