react 18属性和方法

  1. const ReactKeys = [
  2. "Children",
  3. "Component",
  4. "PureComponent",
  5. "Fragment", // 空标签
  6. "Profiler", // 性能审查
  7. "StrictMode", // 严格模式
  8. "Suspense",
  9. "lazy",
  10. "__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED",
  11. "cloneElement",
  12. "createContext",
  13. "useContext",
  14. "createElement",
  15. "createFactory",
  16. "createRef",
  17. "forwardRef",
  18. "useImperativeHandle", // 指定访问的API
  19. "isValidElement", // 是不是一个 react元素
  20. "memo",
  21. "startTransition",
  22. "unstable_act",
  23. "useCallback", // 缓存回调函数
  24. "useDebugValue",
  25. "useDeferredValue",
  26. "useEffect",
  27. "useInsertionEffect",
  28. "useLayoutEffect",
  29. "useId", // 创建当前组件的唯一身份
  30. "useMemo", // 缓存,类似 vue 的 computed 计算属性
  31. "useReducer",
  32. "useRef",
  33. "useState",
  34. "useSyncExternalStore", // 从外部获取数据源
  35. "useTransition",
  36. "version" // 版本号
  37. ]

isValidElement

  1. 必须是 Object对象
  2. 不能为空
  3. 对象中要有 $$typeof 属性,且值必须是 REACT_ELEMENT_TYPE

REACT_ELEMENT_TYPE:一个 Symbol或 16进制的数值。

  1. export const REACT_ELEMENT_TYPE = hasSymbol
  2. ? Symbol.for('react.element') : 0xeac7;

新的API

useId
useSyncExternalStore
useInsertionEffect

useDeferredValue

应用场景:

  1. Select,或 Input的模糊搜索
  2. 复杂计算或网络请求 ```tsx const [inputValue, setInputValue, cancelUpdate] = useDeferredValue(‘’, { timeoutMs: 1000, // 延迟 1000ms,单位毫秒 maximumTimeMs: 5000, // 最长延迟 5000ms 更新,ms equalityFn: (a,b) => a === b, // 状态对比 });

useEffect(() => { return () => { cancelUpdate(); } }, [])

  1. 缺点
  2. 1. 固定的任务设置延迟,和 debounce不一样,会导致数据不一致
  3. 2. 搜索结果不会立即更新,导致关键字和搜索结果不一致,导致数据不一致
  4. 1. 使用 useTransition解决
  5. 3. 如果在状态更新期间,组件已卸载或销毁,可能导致内存泄露
  6. 1. 使用 cancelUpdate 解决
  7. <a name="chkZQ"></a>
  8. ### useId
  9. ID代表,当前组件在组件树中的层级结构,服务端和客户端的ID是一致的
  10. <a name="g6862"></a>
  11. ### useSyncExternalStore
  12. 强制同步更新数据
  13. <a name="JJAzu"></a>
  14. ### useInsertionEffect
  15. useInsertionEffect,需要对 DOM操作时用,例如
  16. - 自动滚动
  17. - 按需加载
  18. ```tsx
  19. function App() {
  20. // 滚动到顶部
  21. useInsertionEffect(() => {
  22. window.scrollTo(0, 0)
  23. })
  24. }

新并发API

startTransition
useDeferredValue

startTransition

不紧急的更新,空闲时更新

  1. import { useEffect, useState, startTransition, useDeferredValue } from 'react'
  2. function App() {
  3. const [state, setState] = useState([])
  4. useEffect(() => {
  5. // 包裹方法
  6. startTransition(() => {
  7. setState(new Array(10000).fill(100))
  8. })
  9. }, []);
  10. // 包裹值
  11. const deferredList = useDeferredValue(state);
  12. return (
  13. <>
  14. {state.map(it => <div key={it}/>{it}</div>)}
  15. {deferredList.map(it => <div key={it}/>{it}</div>)}
  16. </>
  17. )
  18. }

新模式

Concurrent Mode
Strict Mode

Concurrent Mode 并发模式

异步可中断更新

react18 新特性

  1. render
  2. setState批处理
  3. flushSync
  4. 卸载组件时的更新状态警告⚠️
  5. react组件的返回值
  6. Strict Mode 严格模式,重复2次渲染
  7. Suspense不需要 fallback来捕获异常❌

render

  1. import ReactDOM from 'react-dom'
  2. const root = document.getElementById('root');
  3. // react 18
  4. ReactDOM.createRoot(root).render(<App />);
  5. root.unmount(); // 从 DOM中卸载组件
  6. // react 17
  7. ReactDOM.render(<App />, root)
  8. ReactDOM.unmountComponentAtNode(root)

setState批处理

setState不保证 state会立即更新,操作会被延迟批量调用。
批量就是延迟的原因。

setState并不是立即更新的命令,假设setState()是同步的,如果在一次点击函数中更新了两次state,组件就会被渲染两次;
若把setState()收集起来统一处理,组件就只需要被渲染一次。这就是setState()异步的思路;
在一个周期内,每遇到一个setState()React会将它放到队列中,最后会对多个setState()进行批处理。
ReactDOM.unstable_batchedUpdates

flushSync 同步更新

flushSync可以用于强制刷新

  1. import { flushSync } from 'react-dom'
  2. function App() {
  3. const [val, setVal] = useState(0);
  4. const [value, setValue] = useState(0);
  5. function onClick() {
  6. flushSync(() => setVal(val => val + 1))
  7. flushSync(() => setValue(val => val + 1))
  8. }
  9. return (
  10. <Button onClick={onClick}></Button>
  11. )
  12. }

Strict Mode 严格模式

严格模式,二次渲染问题
react 17,使用严格模式,组件会渲染 2次。
react18, 取消了这个限制,安装了 React DevTools后,第二次渲染的日志信息,显示为灰色。

react@version 18.2.0