react 18环境说明
脚手架
安装 create-react-app
npm install -g create-react-app
create-react-app demo-react
环境配置
将 package.json 里面的 "dependencies" 下面 react 的版本由稳定版 rea17 切换为 18beta版本
切换命令
npm uninstall react react-dom --save
npm install react@beta react-dom@beta --save
代码调整
将 src/index.js 进行调整
调整前
import React from 'react';
import { render } from 'react-dom';
import App from './App';
render(<App />, document.getElementById('root'));
调整后
import React from 'react';
import { createRoot } from 'react-dom';
import App from './App';
const root = createRoot(document.getElementById('root'));
root.render(<App />);
useTransition 使用说明
可以用来降低渲染优先级。分别用来包裹计算量大的 function和 value,降低优先级,减少重复渲染次数。
举个例子:搜索引擎的关键词联想。一般来说,对于用户在输入框中输入都希望是实时更新的,如果此时联想词比较多同时也要实时更新的话,这就可能会导致用户的输入会卡顿。这样一来用户的体验会变差,这并不是我们想要的结果。
我们将这个场景的状态更新提取出来:一个是用户输入的更新;一个是联想词的更新。这个两个更新紧急程度显然前者大于后者。
以前我们可以使用防抖的操作来过滤不必要的更新,但防抖有一个弊端,当我们长时间的持续输入(时间间隔小于防抖设置的时间),页面就会长时间都不到响应。而 startTransition 可以指定 UI 的渲染优先级,哪些需要实时更新,哪些需要延迟更新。即使用户长时间输入最迟 5s 也会更新一次,官方还提供了 hook 版本的 useTransition,接受传入一个毫秒的参数用来修改最迟更新时间,返回一个过渡期的pending 状态和startTransition函数。
源码如下:
import React, { useState, useTransition } from 'react';
export default function Demo() {
const [value, setValue] = useState('');
const [searchQuery, setSearchQuery] = useState([]);
const [loading, startTransition] = useTransition(2000);
const handleChange = (e) => {
setValue(e.target.value);
// 延迟更新
startTransition(() => {
setSearchQuery(Array(20000).fill(e.target.value));
});
};
return (
<div className="App">
<input value={value} onChange={handleChange} />
{loading ? (
<p>loading...</p>
) : (
searchQuery.map((item, index) => <p key={index}>{item}</p>)
)}
</div>
);
}
效果如下:
效果是不是和我们平时写的防抖差不多
探索 useTransition 源码
首先下载react18的源码,进入目录 packages\react\src\ReactHooks.js
接着查看 函数 resolveDispatcher
接着在目录 packages\react\src\ReactCurrentDispatcher.js 查找 对象 ReactCurrentDispatcher
然后进入目录 packages\react-reconciler\src\ReactInternalTypes.js,查找 Dispatcher
在目录 packages\react\src\ReactStartTransition.js,查找 startTransition 函数