React 是用 JavaScript 构建 快速响应 的 大型 Web 应用程序 的首选方式之一。
等待资源加载时间和大部分情况下浏览器单线程执行是影响 web 性能的两大主要原因。
等待资源加载:
- 一次请求太多资源?
- 网络请求慢?
- 资源加载失败? 解决方案:
- React.Lazy
- React.Suspense
- ErrorBoundary
const Component = React,lazy(()=import( ./$litem,key} ));
const RenderComponent = (
<Suspense fallback=(“资源加戴中..>
<Component/>
</Suspense>
);
浏览器线程执行
- JS执行
- 浏览器计算样式布局
- UI 绘制 解决方案:
- 异步更新
- 时间切片
- React Fiber
用 React 开发 web 应用
架构:
- 打包配置:JSX ->babel->JS
- 加载优化和错误降级
UI:
- 可复用 UI -> 组件 ->页面。
- 可复用逻辑抽离成 hook。
路由: React Router 向应用中快速地添加视图和数据流,保持页面与URL 间的同步。
状态: 多页面多组件共享信息redux & context
用 React 开发 web 应用-组件
数据:
- 通过定义 state 操作视图
- Mount 时获取数据更新 state
- Ref 保存与视图无直接关系的值unMount 前清空 Ref
通信:
- props父子组件通信
- context & redux 组件信息共享
UI:
- 数据决定视图
- 通过 Ref 获取到 DOM
性能:
- 函数使用 useCallback
- 值或者计算使用 useMemo
- 组件包裹memo
Class 组件:
- 继承 +构造函数
- this
- 生命周期
- render 方法
函数式组件:
- 没有生命周期
- 借助 Hook
- return JSX
函数式相较于 Class的优点
- 代码量骤减,组件干净清爽。
- 没有复杂的生命周期
- 支持自定义 hook,逻辑复用方便。
组件和 Hook 的关系:
- 我们将 UI 拆成多个独立单元,这些单元组合可以构成多种视图展示,这些独立单元就是组件。组件相当于原子。
- hook 贴近组件内部运行的各种概念逻辑,effect、state、context等。hooks 更贴切于电子。
Hook 规则 & 原理
- 只能在 React 函数中调用 Hook
- 在React 函数组件中 或自定义 Hook 中调用自定义 Hook 必须以 use 开头
- Hook 中的 state 是完全隔离的
Hook 过期闭包问题
- 在 JS中,函数运行的上下文是由定义的位置决定的,
- 当函数的闭包包住了旧的变量值时,就出现了过期闭包问题。
React常见 API及作用
- React.Component:类组件基类extends
- React.PureComponent:未实现 shouldComponentUpdate(),内置了props 和state 浅层对比
- React.memo:高阶组件,仅比较 props 变更
- ReactcreateElement:创建并返回 React 元素,不使用 JSX 场景
- React.cloneElement:克隆并返回新 React 元素,并且可以为新元素添加额外
- React.Children.[fn]: propsmap遍历并返回;forEach仅遍历;count子组件数量; only是否只有一个子节点
- React.createRefReact.forwardRef:创建一个 ref,并附加到具体元素上,class 组件中获取 dom 结构常用转发 ref 或者 与 useImperativeHandler 联合使用暴露方法
- React.lazy:实现组件动态加载
- React.Suspense:组件加载过程优雅降级
React常见Hook及作用
- useState:返回一个 state 及更新 state 的函数
- useEffect:可以让你在函数组件中执行某些操作,挂载时、依赖变化时甚至说卸载前。
- useContext:接收最近的上层contex 对象,并返回其值,一般与 createContext 一起使用
- useRef:返回一个可变的 ref 对象,在组件生命周期内持续存在。
- useMemo:参教为计算函数和依赖项,只有在依赖项变化时才调用计算函数。
- useCallback:返回函数的计算值useCallback(fn,deps),相当于 useMemo(0)=>fn,deps),一般返回的是一个新函数。
- useReducer:useState 的更丰富替代方案,返回[state, dispatch],这里 state 可以杂对象,dispatch可以更新这个复杂对象。
- useImperativeHandle:可以给父组件暴露方法。一般与 forwardRef 一起使用
- useLayoutEffect:useEffect 的执行时机是浏览器完成渲染之后,而 useLayoutEffect 的执行时机是浏览器把内容真正渲染到界面之前,和 componentDidMount 等价
父组件给子组件通信
- 知道子组件的表现,直接通过 props 传递即可
不知道具体子组件表现呢?
- props.children
子组件给父组件通信
- 传递信息比如说对象文本等,通过 callback。
- 传递方法?父组件需要调用子组件的一些方法?
一个从 portal 内部触发的事件会一直冒泡至包含 React 树的祖先,即便这些元素并不是 DOM 树 中的祖先。