react 全家桶相关问题:
1.react hooks的原理
- react 16.8以上的fiber架构采用分片渲染的的模式进行渲染,根据优先级来进行组件的渲染工作,FiberNode中有个memoziedState属性,hocks修改组件状态主要是修改fiber节点的memoziedState,可以用数组来模拟实现:
const state = []; let index = 0; const useState = initial => { const current = index; const setState = (val) => { state[current] = val; render(); }; return [state[index++]|| initial,setState]; };
- react 中采用的链表的数据结构:
meoziedState:{ meoziedState, next:{ meoziedState, next... } } // 这就是为什么不能在类组件里,因为两者meoziedState的结果是完全不一致的,类组件里meoziedState和state保持一致,函数组件里是链表结构。useState不能写在分支或循环里,这会破坏它的链式结构
2.React生命周期及自己的理解
- 挂载过程:
- componentWillMount
- componentDidMount
- componentWillUnmount
- 更新过程:
- componentWillReceiveProps
- shouldComponentUptate
- componentWillUpdate
- componentDidUpdate
- render
2.React怎么做数据的检查和变化
- getDerivedStateFromProps 进行props的监听,调用setState就会触发getDerivedStateFromProps setState 主要本质通过队列机制实现对state的更新,执行setState会将state合并后放入状态队列中,而不是立即执行,队列机制可以批量更新state,如果是直接对this.state赋值,则不会加入到状态队列中,下次调用setState时对状态队列进行合并时,会忽略之前直接被修改的state,这样我们就无法合并了,而且实际也没有把你想要的state更新上去。
- 跟vue的区别,主要是setState 不能马上修改state,而vue中的this赋值可以马上改变值,只是view的视图会异步更新,dom完成更新才能执行$nextTick, React在setState之后,会经对state进行diff,判断是否有改变,然后去diff dom决定是否要更新UI。
3.React层面的性能优化
- 3.1. shouldComponentUpdate
- 3.2. pureRenderMixin插件
- 3.3. Immutable Data
- 3.4. this的绑定方法,在constructor中进行绑定事件;
- 3.5. shouldcComponentUpdate
- 3.6. 对每个兄弟组件加上key。
- 3.7 redux性能优化,使用reselect,从reselector中取出缓存
- 3.8. 用函数子组件进行ui和逻辑分离,拆分小组件
- 3.9. react16+中Fiber架构
- 3.10. 分离第三方库代码react-loadable
4.react key的作用是什么,为什么不建议用index?
- react组件中key主要用来diff算法中差异比较的,diff过程中通过key来判断组件是否需要存在,如果用key的话在某种情况下知识key的顺序变了,react只会对现存组件进行移动,比如input框里面已经填写了,移动后input框里面的值没有改变,还是原来的值,知识input框的书序发生修改了
5.react异步渲染的概念,介绍Time Slicing 和 (Suspense,lazy)
-
React 16.x的两大新特性 Time Slicing, Suspense
-
React 16.6:支持代码拆分的 Suspense 组件(已经发布)
-
React 16.7:React Hooks(~ 2019 年 Q1)
-
React 16.8:并发模式(~ 2019 年 Q2)
-
React 16.9:支持数据提取的 Suspense 组件(~ 2019 年年中)
-
由原始的防抖到异步的方案-Time Slicing(时间切片)requestIdleCallback和requestAnimationFrame,其中requestIdleCallback在浏览器空闲时候执行,第二个参数timeout,如果浏览器没有空闲时间,则强制执行,requestAnimationFrame在浏览器渲染的每一帧都执行。
-
lazy的实现类似于promise
// 第一步: 用 Suspens 组件包裹子组件 import { Suspense } from 'react' <Suspense fallback={<Loading />}> <ChildComponent> </Suspense> //第二步: 在子组件中使用 unstable_createResource: import { unstable_createResource } from 'react-cache' const resource = unstable_createResource((id) => { return fetch(`/demo/${id}`) }) // 第三步: 在 Component 中使用第一步创建的 resource: const data = resource.read('demo')
-
Suspense 会维护一个updateQueue, updateQueue 会批量更新,这个 updateQueue 里面装着的是 promise
6.react diff算法理解
7.页面优化:
- 小程序优化:
1.沟通:确认页面,平台首页跳转
2.上面一个页面还在执行,轮播图;支付宝小程序会出现,微信小程序会
onShow onLoad,直接跟支付宝对接,直接跳转到确认开锁页
3.函数分析工具 图片加载 同步函数的调用await(函数缓存,函数kelihuq,页面缓存,http缓存) api重复调用用缓存 dns解析到同一个页面 现在调研http2,getInfo 200ms延时 流程优化 健康分:首屏性能,稳定性(api,js报错,白屏) 首屏优化:api请求,时间维度,页面维度的缓存 元素的异步调用 png改成webp ,同层渲染(地图上的元素),初始化进入会掉6次 调研:健康分从65 到80分
8.react 16.X声明周期的改变
-
新增生命周期:
-
1.getDerivedStateFromProps 新的静态getDerivedStateFromProps生命周期在组件实例化以及接收新props后调用。它可以返回一个对象来更新state,或者返回null来表示新的props不需要任何state更新。 与componentDidUpdate一起,这个新的生命周期应该覆盖传统componentWillReceiveProps的所有用例。
-
2.getSnapshotBeforeUpdate 新的getSnapshotBeforeUpdate生命周期在更新之前被调用
getSnapshotBeforeUpdate(prevProps, prevState) {
// ...
}
- 舍弃的生命周期
- UNSAFE_componentWillMount
- UNSAFE_componentWillReceiveProps
- UNSAFE_componentWillUpdate
9.介绍高阶组件
10.SetState为什么默认是异步,SetState什么时候是同步的
- 在 React 的 setState 函数实现中,会根据一个变量isBatchingUpdates判断是直接更新 this.state 还是放到队列中回头再说,而 isBatchingUpdates 默认是 false,也就表示 setState 会同步更新 this.state,但是,有一个函数 batchedUpdates,这个函数会把 isBatchingUpdates 修改为t rue,而当 React 在调用事件处理函数之前就会调用这个 batchedUpdates,造成的后果就是由 React 控制的事件处理过程 setState 不会同步更新 this.state。 在React的setState函数实现中,会根据一个变量 isBatchingUpdate 来判断是直接同步更新this.state还是放到队列中异步更新 。React使用了事务的机制,React的每个生命周期和合成事件都处在一个大的事务当中。在事务的前置钩子中调用batchedUpdates方法修改isBatchingUpdates变量为true,在后置钩子中将变量置为false。原生绑定事件和setTimeout异步的函数没有进入到React的事务当中,或者当他们执行时,刚刚的事务已近结束了,后置钩子触发了,所以此时的setState会直接进入非批量更新模式,表现在我们看来成为了同步SetState
11.Immutable data
- javascript 中的对象一般是可变的,因为使用了引用赋值,对象修改了会造成以前对象值的变化,但是用深拷贝会造成性能的问题,Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),利用老数据构建新数据,也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化
1.Immutable 降低了 Mutable 带来的复杂度
2.节省内存
3.并发安全
12.fiber架构
- facebook在react16增加fiber结构,其实并不是为了减少组件的渲染时间,事实上也并不会减少,最重要的是现在可以使得一些更高优先级的任务,如用户的操作能够优先执行,提高用户的体验,至少用户不会感觉到卡顿~