react 简介和特性
react 用于构建用户界面
react的特点
- 声明式
- 组件化
- 跨平台编写
一、react 哲学
react 是用js 构建快速响应和大型web应用程序的首选方案之一。
等待资源加载时间和大部分情况下浏览器单线程执行是影响web性能的两大主要原因。
等待资源加载:
- 一次请求太多资源
- 网络太慢
- 资源加载失败
浏览器线程执行
- js 执行
- 浏览器计算样式布局
- ui 绘制
由于js的执行会阻塞浏览器的渲染,因此在执行一些比较耗时的js任务时,页面上的渲染就有可能被阻塞,此时表现出来掉帧的效果。react 在内部优化了这个点,仅在浏览器空闲时执行计算,也就是react fiber。
二、react 的优缺点
优点
- 快速响应 react fiber
- 组件化:复用性强
- 声明式编程
- 跨平台:只需要修改渲染器
缺点
- 大型应用,需要配套学习
- 不适合小型应用,需要 babel 的处理
react 基础温故知新
用 react 开发 web 应用
组件
class 组件
- 继承 + 构造函数
- this
- 生命周期
- render 方法
函数式组件
- 没有生命周期
- 借助 hook
- return JSX
函数式相对于class的优点
- 代码量骤降,组件干净清爽
- 没有复杂的生命周期
- 支持自定义hook,逻辑复用方便
组件和hook的关系
- 组件相当于原子
- hook更贴近组件内部运行的逻辑,服务于组件更贴切于电子。
hook 规则和原理
- hook 只能在最顶层使用,react 依赖 hooks 的调用顺序(链表)
- 只能在react函数组件内或自定义hooks内使用hooks
- 自定义hooks必须以use开头
- hook中的state是完全隔离的
react常见的 api 及作用
- Component: 类组件的基类
- PureComponent:未实现scu,内置了props和state的浅对比
- memo:高阶组件,仅比较props变更
- createElement:创建并返回 react 元素
- cloneElement:clone 并返回新的 react 元素,同时可以未新元素添加props
- Children.[Fn]:用于遍历,支持map、forEach、count、only等方法
- createRef:创建一个ref,常用于获取dom元素
- forwardRef:转发ref
- lazy:实现组件动态加载
- Suspense:组件加载过程降级
常见的hooks及作用
- useState:返回一个state及更新state的函数
- useEffect:在函数组件中某些时机执行某些操作
- useContext:接收最近的context对象,配合createContext使用
- useRef:创建一个可变的ref,在组件生命周期中持续存在
- useMemo:参数为计算函数和依赖项,只有依赖变化才会调用计算函数,返回函数的计算值
- useCallback:根据依赖项,返回一个新的函数,相当于useMemo返回一个新函数
- useReducer:useState的更丰富的替代方案,可以定义更复杂的 action
- useImperativeHandle:给父组件暴露方法,配合forwardRef使用
- useLayoutEffect:类似useEffect,区别是执行时机是浏览器把真正的内容渲染到页面之前,等价于componentDidMount
三、业务场景案例
拆分组件
组件拆分是为了更好的进行代码复用,一般有以下方式
- 按内容的表现
- 按布局的位置
- 按动画效果
父组件给子组件通信
- 直接通过 props 传递
- 通过props.children传递
// 直接传递
<Input value={xxx}>
// 通过props.children
React.Children.map(children, (child) => {
return React.cloneElement(child, commonProps)
})
子组件给父组件通信
- 通过callback参数传递
- 父组件定义一些方法给子组件调用
组件间的共享信息
当兄弟组件或者跨多级组件之间需要进行通信时,如果还是用props或者callback的方式进行,就需要层级提升或者层层传递,所以可以使用下面几种方式进行组件间的通信。
- context
- reducer
- react-redux 库
组件性能优化
我们知道react在props和state变化时都会进行重新渲染,实际应用时会存在props或state更新,但是页面不需要重新渲染的情况,此时就需要shouldComponentUpdate来控制组件是否进行重新渲染
- shouldComponentUpdate:通过返回值控制组件是否需要重新渲染
- memo:通过React.memo包一些组件
- useMemo:添加指定依赖
- useCallack:添加指定依赖
组件挂载位置
在实际开发时,会存在书写位置和挂载位置不相同的场景,比如抽屉组件、弹窗组件等,这些组件一般是挂载在body上的,此时就可以通过 createPortal 来实现自定义组件的真实挂载的位置,比如 body;需要注意的是,组件的冒泡事件会冒泡到react树的祖先而不是dom树的祖先。
...
createPortal(component, document.body)
...
如何进行逻辑复用
react 使用自定义 hooks 来进行逻辑的复用。