重点内容:
- React 简介与特性
- React 更新流程
- hook 规则
- 常见 API
- 业务场景案例
详细知识点介绍:
React 简介与特性:
React,用于构建用户界面的 JavaScript 库
特性:
- 声明式
- 组件化
- 跨平台编写
React 更新流程:
React 会依据 current 创建一颗新的 workInProgerss 树,然后用一个 alternate属性 连接 workInProgerss 树和 current 树,完成后,fiberRoot的指针会指向 workInProgerss 树,使其变成 current 树
Scheduler(调度器):
- 维护时间切片
- 与浏览器任务调度
- 优先级调度
Reconciler(协调器):
- 将 JSX 转化为 Fiber
- Fiber 树对比
- 确定本次更新的 Fiber
Renderer(渲染器):
- 渲染器用于管理 React 树
- 使其根据底层平台进行不同的调用
React 开发:
组件:
- Class 组件:
- 继承 + 构造函数
- this
- 生命周期
- render 方法
- 函数式组件:
- 无生命周期
- 借助 Hook
- return JSX
函数式 相对于 class 的优势:
- 代码量减少,组件干净清爽
- 没有复杂的生命周期
- 支持自定义hook,逻辑复用方便
组件 与 Hook 关系:
- 将 ui 拆分成多个独立单元,这些单元组合能构成多种视图展示,这些独立单元就是组件。组件相当于原子
- hook 贴近组件内部运行的各种概念逻辑。hook 更贴近电子
Hook 规则&原理:
只能在最顶层使用 Hook
只能在 React 函数中调用 Hook:
- 在 React 函数组件中 或自定义 Hook 中调用
- 自定义 Hook 必须以 use 开头
- Hook 中的 state 是完全隔离的
Hook 过期闭包问题:
在 JS 中,函数运行的上下文是由定义的位置决定,当函数的闭包,包住旧变量值,就会出现过期闭包问题
解决方案: 调用 useEffect,在它的第二个参数 依赖项 中添加 需要的数据即可
function WatchCount() {
const [count, setCount] = useState(0)
useEffect(() => {
const id = setInterval(() => {
console.log(`Current Count is ${count}`)
}, 1000)
return () => {
clearInterval(id)
}
// useEffect 第二个参数 依赖项 中添加 需要的数据即可
}, [count])
return (
<div>
{count}
<button onClick={() => setCount(count + 1)}>click</button>
</div>
)
}
React 常见 API:
| API | 作用 |
|---|---|
| React.Component | 类组件基类 extends |
| React.PureCompont | 未实现 shouldComponentUpdate(),内置 props 和 state 浅层对比 |
| React.memo | 高阶组件,仅比较 props 变更 |
| React.createElement | 创建并返回 React 元素,不使用 JSX 场景 |
| React.cloneElement | 克隆并返回新的 React 元素,并且可以为新元素添加额外的 props |
| React.Children.[fn] | map 遍历并返回;forEach仅遍历;count子组件数量;only是否只有一个子节点 |
| React.createRef | 创建一个 ref,并附加到具体元素上,class 组件中,获取 dom 结构常用 |
| React.forwardRef | 转发ref 或与 useImperativeHandle联合使用暴露方法 |
| React.lazy | 实现组件动态加载 |
| React.Suspense | 组件加载过程优雅降级 |
React 常见 Hook:
| Hook | 作用 |
|---|---|
| useState | 返回一个 state 以及 更新 state 的函数 |
| useEffect | 在函数组件中执行某些操作,挂载时、依赖变化时、卸载前 |
| useContext | 接受最近的上层 context 对象,并返回其值,一般和 createContext 配套使用 |
| useRef | 返回一个可变的 ref 对象,在组件生命周期内持续存在 |
| useMemo | 参数为 计算函数 和 依赖性,只有依赖项发生变化时才会去调用计算函数。返回函数的计算值 |
| useCallback | useCallback(fn, deps), 相当于 useMemo(() => fn, deps),一般返回的是一个新函数 |
| useReducer | useState 的更丰富的替代方案,返回[state, dispatch],这里的 state 可以是复杂对象 ,dispatch 可以更新这个复杂对象 |
| useImperativeHandle | 给父组件暴露方法,一般与 forwardRef 一起使用 |
| useLayoutEffect | useEffect 执行时间是浏览器完成渲染后,useLayoutEffect 执行时机在浏览器把内容真正渲染到界面之前,和 componentDidMount 等价 |