react 虚拟dom
虚拟dom是什么
虚拟dom相当于在js和真实dom中间加了一个缓存。利用dom diff算法避免没必要的dom操作。从而提高性能。
实现过程
1. 用js对象结构表示dom树的结构。
2. 用这个树构建一个真正的dom树,当状态变化时,重新构建一个新树。
3. 用新树和旧树比较,记录两颗树的差异并应用到真正的dom上。
虚拟dom和真实dom区别
减少dom操作,虚拟dom将多次操作合并为一次。
真实dom:
1. 更新缓慢。
2. 可以直接更新html
3. 如果元素更新创建新dom
4. dom操作代价高
5. 内存消耗大
虚拟dom:
1. 更新更快
2. 无法直接更新html
3. 如果元素更新,更新jsx
4. dom操作简单。
5. 很少的内存消耗。
react组件通信
1. 父传子:通过props
2. 子传父:props+回调。父组件将函数传递给子组件。子组件调用函数并传递参数。
3. 兄弟传值:由父节点转发。
4. 跨层通信:context。
5. 发布-订阅:
6. 全局状态管理工具:redux或mobx。
redux原理
redux是前端最热门的js库之一,是js的状态容器。用于整个应用的状态管理。
数据如何通过redux传递:
1. 首先,用户发出action,通过dispatch发送。
2. 然后,store自动调用reducer,并且传入两个参数:当前state和收到的action,reducer返回新的state
3. state一旦变化就调用,store调用监听函数,更新view。
redux 原则:
1. 单一事实来源:整个应用状态存储在单一store中的对象里。
2. 状态只读:改变状态的唯一方式是触发action
3. 使用纯函数更改:指定状态如何通过操作转换。
对“单一事实来源”的理解:
store将状态存储在同一个地方,更容易追踪,调试,检查。
redux组成
1. action - 定义事件
2. reducer -
3. store
4. view
React生命周期
React生命周期三个阶段:
1. 初始渲染阶段:这是组件即将开始进入dom的阶段。
2. 更新阶段:一旦组件被添加到dom,它只有在props或状态变化时才可能更新dom。
3. 卸载阶段:组件生命周期最后的阶段,组件被销毁并从dom中移除。
React生命周期函数
挂载阶段:
1. constructor:构造函数,最先被执行。
2. getDerivedStateFromProps:属性改变,想要修改state时使用。
3. render:纯函数,只返回需要渲染的东西。
4. componentDidMount:组件挂载后执行。
更新阶段:
1. getDerivedStateFromProps:prop更新,state未更新。
2. shouldComponentUpdate:prop和state更新了,返回true表示触发重新渲染,返回false表示不重新渲染。
3. render
4. componentDidUpdate: 组件更新后执行。
卸载阶段:
1. componentWilUnmount:组件被销毁时执行。
react router
<switch>
<route exact="" path="’/’" component="{Home}/">
<route path="’/posts/:id’" component="{Newpost}/">
<route path="’/posts’" component="{Post}/">
</route>
</route>
</route>
</switch>
什么是react router
react 路由是构建在react上的路由库,使url与网页上显示的数据保持同步。用于开发单页web应用。
为什么需要react router
router用于定义多个路由,当url与router内的路由匹配时,用户会被重定向到特定路由。
为什么router需要switch
switch可以使当url按顺序匹配路由,找到第一个项后,渲染指定路径。
hooks优点
1. 更容易复用代码,解决类组件难以复用逻辑的问题。类组件复用方式是高阶组件和renderProps。hooks复用的方式
每调用一次都会生成一个状态,虽然状态和副作用的存在依赖于组件,但他们可以在组件外定义。
2. 代码更清爽。函数式编程风格,函数式组件、状态保存在运行环境、每个功能包裹在函数中。
3. 代码量更少,向props取值更简单,函数组件的取值直接从父级作用域取,类组件需要先访问this,再访问state和props。更改状态从this.setState({count:1})变成了setCount
4. 更容易发现无用的状态和函数。
5. 更容易拆分组件,函数组件写小组件比类组件方便。
缺点:
1. useEffect 的依赖参数不好写,useEffect容易出错,它是响应式的,当某个依赖项变化时才会被调用。
2. 状态不同步,每个函数有一份独立的作用域,当处理复杂逻辑时,会碰到引用不是最新的问题。
为什么浏览器无法读取jsx
浏览器只能处理js对象,不能读取jsx,为了使用浏览器能读取jsx,使用babel转换器,转为js,然后传给浏览器。
你对refs的理解
处理对React元素或组件的引用。当需要进行dom测量或向组件添加方法时有用。
应用:
1. 管理焦点、选择文本;
2. 触发式动画;
3. 与第三方继承。
React事件绑定原理
React并不是将click绑定到该div的真实dom上,而是在document处监听所有事件,当事件发生并冒泡至document时,react将事件内容交给真正的处理函数运行。这样减少内存消耗,还能在组件销毁时统一订阅和移除。
另外冒泡到document上的事件也不是原生浏览器事件,而是react合成事件,所以如果不想要冒泡的话要用event.preventDefault而不是event.stopPropagation。
redux-saga和mobx比较
1. 状态管理
redux-saga是redux 的一个异步处理的中间件。
mobx是数据管理库,和redux一样。
2. 设计思想
redux-saga属于flux体系,是函数式编程思想。
mobx不属于flux体系,是面向对象和响应式编程思想。
3. 特点
redux-saga因为是中间件,更关注异步处理,通过generator函数将异步变为同步,代码可读性高,结构清晰。
mobx更简单灵活,store中包含state和action。
4. 数据可变性。
redux-sage强调state不可变,不能直接操作state,通过action和reducer在原来的state基础上返回新的state。
mobx直接在方法中更改state。
5. 写法
redux-sage
setState是同步还是异步
1. setState在合成事件和钩子函数中是异步的。在原生事件和setTimeout是同步的。
2. setState的异步并不是内部由异步代码实现,其本身执行过程和代码是同步。只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法马上拿到更新后的值。当然可以通过第二个参数callback中拿到更新后的值。
3. setState的批量更新优化也是建立在异步之上。在原生事件和setTimeout中不会批量更新。
props和state区别
props和state都是普通js对象:
1. state是组件自己管理数据,控制自己的状态;
2. props是外部传入的数据,不可变;
3. 没有state的组件叫无状态组件,有state的组件叫有状态组件。
4. 多用props,少用state。
当调用setState时,react render是如何工作
虚拟dom渲染:当render方法被调用时,它返回一个新的虚拟dom结构,当调用setState时,render被再次调用。
原生dom渲染: