React18

Render API

ReactDOM.render(<App />, root); // 17
ReactDOM.createRoot(root).render(<App />); //18, 并发模式

setState 自动批处理

批处理:多个setState只会触发一次渲染

之前
事件处理函数 批处理
promise、setTimeout、原生事件 不批处理

现在批处理

flushSync

退出批量,下面的代码会渲染两次。如果一个flushSync中有多个setState还是会批处理。

flushSync(() => {
  setCount1(count => count + 1);
});
flushSync(() => {
  setCount2(count => count + 1);
});

useId

支持同一个组件在客户端和服务端生成相同的唯一的 ID,避免 hydration 的不兼容

useSyncExternalStore

第三方状态管理库使用的(redux),解决并发模式下的撕裂问题。

useInsertionEffect

这个 Hooks 只建议 css-in-js 库来使用,一般用于提前注入 <style> 脚本。

Concurrent Mode(并发模式)

异步可中断更新。createRoot(root).render() 开启并发模式。

startTransition

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  const [isPending, startTransition] = useTransition();
  useEffect(() => {
    // 使用了并发特性,开启并发更新
    startTransition(() => {
      setList(new Array(10000).fill(null));
    });
  }, []);
  return (
    <>
      {list.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

setList会被标记为不紧急更新,可以被其他紧急更新抢占。

比如有一个input受控组件,在渲染列表时更新input,就会终端列表渲染。

useDeferredValue

useTransition 是把更新任务变成了延迟更新任务,而 useDeferredValue 是产生一个新的值,这个值作为延时状态。(一个用来包装方法,一个用来包装值)

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  useEffect(() => {
    setList(new Array(10000).fill(null));
  }, []);
  // 使用了并发特性,开启并发更新
  const deferredList = useDeferredValue(list);
  return (
    <>
      {deferredList.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

普通模式(未开启并发更新)

const App: React.FC = () => {
  const [list, setList] = useState<any[]>([]);
  useEffect(() => {
    setList(new Array(10000).fill(null));
  }, []);
  return (
    <>
      {list.map((_, i) => (
        <div key={i}>{i}</div>
      ))}
    </>
  );
};

这种古来的写法就是未开启并发更新,会一次渲染全部1万个元素

这种将长任务分拆到每一帧中,像蚂蚁搬家一样一次执行一小段任务的操作,被称为时间切片(time slice)

fiber

  1. 作为架构来说,
  • 在旧的架构中,Reconciler(协调器)采用递归的方式执行,节点数据保存在递归的调用栈中,无法中断;
  • 在新的架构中,Reconciler(协调器)是基于fiber实现的,节点数据保存在fiber中,可以中断。
  1. 作为数据结构来说,每个fiber对应一个组件,保存了这个组件的类型对应的dom节点信息,这个时候,fiber节点就是我们所说的虚拟DOM。
  2. 作为动态工作单元来说,fiber节点保存了该节点需要更新的状态,以及需要执行的副作用。
posted @ 2024-04-16 17:02  让速不让路  阅读(12)  评论(0编辑  收藏  举报