这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
setState是同步更新还是异步更新的
setState概念
用于变更状态,触发组件重新渲染,更新视图UI
setState并非是真异步而是看上去像异步,通过
isBatchingUpdates判断是否塞进更新队列还是直接更新,true为异步操作,false为直接更新
何时isBatchingUpdate为true?
在React可以控制的范围为true,比如React生命周期事件和合并事件
在原生事件比如
setTimeoutaddEventListenersetInterval为同步更新
为什么setState不改为同步更新
保持内部的一致性,
props的更新不是同步启用并发更新,完成异步渲染
React如何面向组件跨层级通信
分类
- 父子组件通信
- 兄弟组件通信
- 跨层级通信
实现
父子组件通信
父->子
1.在函数式组件外导入 import { useState } from 'react' 2.在函数式组件类 const [num, setNum] = useState(0) 这样我们就给num赋予了初始值 3.在子组件标签上定义 <Son num={num}></Son> 4.在子组件内部的函数式参数上写上实参props 5.直接调用 props.num子->父
依赖回调函数
兄弟组件通信
将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
跨层级组件通信
Context
- 导入并调用
createContext方法,得到Context对象,导出对象- 使用
Provider组件包裹根组件,并通过value属性提供要共享的数据- 在任意后代组件中,如果希望获取公共数据: 导入
useContext;调用useContext(第一步中导出的context) 得到value的值全局事件和全局变量
不推荐,简单用于存储临时的事件与变量
状态管理框架
FluxReduxMobx
列举一种你常用的状态管理框架
Flux:提出了MVC以外的成功实践:单向数据流
Redux
三原则
- 单一数据源Store:整个应用的state被储存在一个object tree中,并且这个object tree只存在唯一一个Store中
- 纯函数Reudcer:为了描述Action如何改变状态树,编写一个纯函数的Reducer
- state是只读的:唯一个可改变state的方法是触发action,Action是用于描述已发生事件的普遍对象
如何解决副作用?
副作用概念
任何具备业务价值的Web应用必要执行复杂逻辑如AJAX请求等异步工作,这类逻辑使函数在每次执行过程中产生不同的变化,这样与外界交互叫做副作用
Redux是怎么解决副作用的?
在Dispatch时有middleware中间层拦截分发的Action添加额外行为,可添加副作用
允许Reducer层直接处理副作用
一类方案:Redux-thunk 作用: 处理异步Action
const createThunkMiddleware = (extraArgument)=>{ return ({dispatch,getState})=>(next)=>(Action)=>{ if(typeof Action === 'function'){ return Action(dispatch,getState,extraArgument) } return next(Action) } } const thunk = createThunkMiddleware() thunk.withExtraArgument = createThunkMiddleware export default thunk
Redux-promiseRedux-sagaRedux-observable社区方案
Rematchdva
优点
- 结果可预测
- 代码结构严格,易于维护
- 模块分离清晰,异步编写单元测试
- 定位问题简单快捷
- 单一数据源使服务端同构变得简单快捷
- 社区生态好,各问题的解决方案多
实现redux
createStore 即通过createStore,注入Reducer与middleware,生成Store Store对象的getState,subscrible与dispatch getState获取当前状态树,subscribe函数订阅状态树变更,dispatch发送action
Mobx
Mobx的监听方式
在Mobx5之前,采用
Object.defineProperty在Mobx5之后,采用
Proxy方案类似于Vue
优点
- 样板代码少
- 简单上手快
- 响应式更新数据让开发人员心智负担小