react基础简要总结 | 青训营笔记

111 阅读3分钟

react简介与特性

特点

  • 声明式
  • 组件化
  • 跨平台(react-native)

react哲学

  • 等待资源加载和单线程执行限制了性能
  • React.Lazy动态加载, React.Suspense提示, ErrorBoundary出现错误渲染降级UI(高阶组件)
  • 异步更新, 时间切片, React Fiber
  • 更新相关组件: scheduler调度器(任务调度), reconciler协调器(jsx转为fiber树并管理), renderer渲染器(根据平台渲染)

优缺点

  • 优点: 快速响应, 组件化, 声明式编程, 跨平台
  • 缺点: 大型应用需要配套学习, 不适合小型应用\

react基础

总体

  • web应用: 架构(jsx), UI(可复用UI->组件,可复用逻辑->hooks), 路由(react-router), 状态(redux&context)
  • 组件: UI(ref), 数据(state,ref), 通信(props, context,redux), 性能(useCallback, useMemo)

组件

  • class组件: 继承+构造函数, 数据和方法用this, 生命周期, render方法
  • 函数式组件: 没有生命周期, 借助hook来使用state,effect,context等特性
  • 函数式组件代码量更小,没有复杂生命周期,hooks复用性高; 组件和hooks相当于原子和电子

hook的规则和原理

  • 只能在最顶层使用hook, 因为react靠调用顺序来对应useState和state
  • 只能在函数组件或自定义hook中使用hook, 自定义hook以use开头
  • 过期闭包问题,多重嵌套中,内层函数引用的闭包不会随外层变化; react中useEffect的第二个参数用来避免这个问题\

react常见api

  • Component 组件基类, PureComponent 没有shouldComponentUpdate,memo 高阶组件,比较props变更
  • createElement 创建元素 cloneElement 克隆元素 Children.[Fn]遍历相关
  • createRef 创建引用,用于获取dom结构; forwardRef 转发ref
  • lazy 动态加载 Suspense 优雅降级

常见hook

  • useState 返回state及更新函数 , useReducer 返回state复杂对象 dispach 更新方法
  • useEffect 在特定时刻执行操作 , useMemo 计算依赖, useCallback大致类似, useLayoutEffect 渲染之前
  • useContext 接收上层context对象, useImperativeHandle 给父组件暴露方法
  • useRef 返回可变ref对象

业务场景案例

以火山引擎为例

划分组件

  • Layout: NavBar导航, Main Content主要内容, Float Button 悬浮栏, Footer页脚
  • Page: 产品页Banner, 卡片集合Card Group, 幻灯片集合Slider Group, 帮助Help Docs
  • Component: BlockHeader(tag,header); BlockWrapper(backgroundType,animate); SlideButton(onclick, icon, animate); SizeText;AnimationWrapper

通信

  • 父子组件通信 SizeWrapper, React.Children.map(()=>cloneElement(chlid, commonprops))
  • 子组件给父组件通信: 例如方法定义在里,按钮在外;用useImperativeHandle给ref添加方法,通过forwardref转发ref,在外层使用formRef.current?.change()
  • 组件间共享信息(context&reducer): 定义一个GlobalContext, 组件用useContext获取,用createStore创建容器,用useContext获取dispatch和state 然后组件调用dispatch改变
  • 组件间共享信息(react-redux):reducer和createStore类似,传入方法是往组件的props注入store的state和store

组件性能优化

  • 父组件重新渲染后,子组件不管依赖有没有变,也会重新渲染(name变了,导致子组件counter也重新渲染)
  • 类组件用shouldComponentUpdate, 函数组件用React.memo包裹; 其中比较时注意increment函数每次渲染时会重新定义,应该用useCallback定义;这样实现了count不变,counter不重新渲染.
  • calcValue用useMemo定义,实现了count不变,calcValue不变; 另外useMemo返回值,useCallback返回函数;

组件挂载位置

  • createPotral改变真实dom渲染位置,例如把全局渲染的drawer在某个div中渲染
  • 同时冒泡的位置也是在原容器,(自定义事件,按照react树而非dom树冒泡)

代码复用-

  • 例子:useRequest, const {run,loading,...extra} = useRequest(RequestFn,{inteval})
  • 入参: requestFn请求函数, auto自动发送,ready前置条件,inteval轮询间隔
  • 状态(state): loading请求中, polling轮询中,result结果
  • 方法: run, cancelpolling取消
  • 变量:timer时间, reqParams记录请求参数