【React 18 新功能】什么是自动批处理?【简单易懂,适合初学者】
首先
接下来,我们将继续解释React的新功能之Automatic Batching!这是React18中非常重要的功能之一,所以请务必阅读本文以了解概述!
“Automatic Batching是什么…?”
从以下公式中引用
自动批处理是指React为了性能而将多个状态更新分组并合并为单个重新渲染。在自动批处理之前,只有React事件处理程序中的更新才会进行批处理。使用promise、setTimeout、本地事件处理程序或其他任何事件中发生的更新默认情况下不会进行批处理。通过自动批处理,这些更新也会自动进行批处理。
简单来说,它指的是通过将更新集成到一次重新渲染中来提高性能的功能。
在React18中,对于promise、setTimeout和then等事件,也会自动进行批处理。通过这个功能,React内部将执行重新渲染的工作整合在一起,而不是每次调用set函数都进行重新渲染,可以同时进行更新并一次性完成!
由于实际编写和运行代码比概念理解更易于理解,我认为我们应该动手操作一下!
让我们亲自试着运行这段代码吧
在React 17版本中的行为。
请参照以下文章,将版本降级至17。
请创建一个用于更新以下状态以进行实际操作确认的文件!
import { useState } from "react"
export const AutoBatchEventHandler = () => {
console.log('AutoBatchEventHandler rendered!')
const [state1, setState1] = useState<number>(0)
const [state2, setState2] = useState<number>(0)
const onClickUpdateButton = () => {
console.log(state1)
setState1(state1 => state1 + 1)
console.log(state1)
setState2(state2 => state2 + 2)
}
return (
<div>
<p>Automatic Batching確認用(React17)</p>
<button onClick={onClickUpdateButton}>update state!</button>
<p>State1: {state1}</p>
<p>State2: {state2}</p>
</div>
)
}
请您将原始的App.tsx中的调用方式描述如下。
import './App.css';
import { AutoBatchEventHandler } from './components/AutoBatchEventHandler';
function App() {
return (
<div className="App">
<AutoBatchEventHandler />
</div>
);
}
export default App;
只需要一种选项:
从上面的gif中可以看出,即使进行了多次状态更新,重新渲染也只会发生一次。
即使在事件处理程序中更新了许多状态,状态更新会被批处理成一个处理,所以重新渲染只会发生一次!
这是React17中已经纳入的功能。
请在其他事件处理程序之外也要确认操作,因此请创建以下文件!
import { useState } from "react"
type Comment = {
postId: number;
id: number;
name: string;
email: string;
body: string;
}
export const AutoBatchOther = () => {
console.log('AutoBatchOther rendered!')
const [comments, setComments] = useState<Comment[] | null>(null)
const [isFinishApi, setIsFinishApi] = useState<boolean>(false)
const [state3, setState3] = useState<string>('')
const onClickExcuteApi = () => {
fetch('https://jsonplaceholder.typicode.com/comments/')
.then(response => response.json())
.then((data) => {
setComments(data)
setIsFinishApi(true)
setState3('updated')
})
}
return (
<div>
<p>Automatic Batching確認用(イベントハンドラ外)</p>
<button onClick={onClickExcuteApi}>API更新!</button>
<p>isFinishApi: {isFinishApi ? 'true' : 'false'}</p>
{comments?.map((comment) => <p key={comment.id}>{comment.body}</p>)}
</div>
)
}
App.tsx的中文翻译为:应用.tsx。
import './App.css';
import { AutoBatchEventHandler } from './components/AutoBatchEventHandler';
+import { AutoBatchOther } from './components/AutoBatchOther';
function App() {
return (
<div className="App">
<AutoBatchEventHandler />
+ <AutoBatchOther />
</div>
);
}
export default App;
使用Fetch API,AutoBatchOther.tsx文件的代码的简要说明是获取并显示评论数组。
如果您想了解有关Fetch API的更多信息,请点击这里。
这次我们正在使用json placeholder来进行数据获取!
现在我们来确认一下行为。
当在浏览器上运行时…
我觉得通过上述内容就可以理解,当执行 onClickExcuteApi 时,我认为会有3次重新渲染。这次是因为在.then的内部,set函数被调用了3次,所以产生了像gif一样的行为。
React18的行为
请先将Strict模式关闭。
如果不清楚的话,请参考以下内容。
请在 React18 中准备相同的源代码!
将 Automatic Batching 确认用(React17)更改为 Automatic Batching 确认用(React18)的显示名称,并进行操作确认。
我认为在事件处理程序外部,行为可能不会像React17一样批处理,因此可能会发生多次重新渲染。
通过升级到React18版本,特别是开发者无需手动操作,系统会自动进行批处理。正如所述,这就是自动批处理。
关于FlushSync的内容
我们可以用flushSync将此操作显式地转为批处理。
请在src/components/AutoBatchiEventHandler.tsx中添加以下代码!
import { useState } from "react"
+ import { flushSync } from "react-dom"
export const AutoBatchEventHandler = () => {
console.log('AutoBatchEventHandler rendered!')
const [state1, setState1] = useState<number>(0)
const [state2, setState2] = useState<number>(0)
const onClickUpdateButton = () => {
console.log(state1)
+ flushSync(() => {
setState1(state1 => state1 + 1)
+ })
console.log(state1)
setState2(state1 => state1 + 2)
}
return (
<div>
<p>Automatic Batching確認用(React18)</p>
<button onClick={onClickUpdateButton}>State更新!</button>
<p>State1: {state1}</p>
<p>State2: {state2}</p>
</div>
)
}
这样的话…
我认为你可以从gif中看到,每当State更新时,它会重新渲染两次。
总结
本次我们总结了关于自动批处理的内容。
如果对官方文档理解不清楚的人,建议可以实际查看本文的源代码并在开发环境中执行,这样可能会更容易理解其含义。
我想在Qiita Engineer Festa期间,再次写一篇关于React新功能的解释性文章。
希望本篇所能對大家有所助益。
参考资料和教学材料
深入理解React v18的功能将成为未来前端开发所必备的知识。