关于Strict模式的更改以及自动批处理的相关事项

首先

虽然React18发布已经过去一年多了,但我认为仍有人只停留在React17之前的信息更新,或者只适合React初学者的内容。这次我们来学习一下Strict模式和自动批处理。关于Transition/Suspense,我打算单独总结。

在谈论这个问题之前

React18已经发布,并重新设计了用于客户端和服务器的API。
为了使用React18的功能,首先需要改变渲染的方法。

修改的地方

在React17之前,我们使用ReactDOM.render将内容渲染到根节点。

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(
    <App />
, document.getElementById('root'));

在React 18中,可以使用ReactDOM.createRoot来进行对root的渲染。
还需要将导入语句从’react-dom’更改为’react-dom/client’。
目前,如果使用create-react-app,它会自动兼容这种渲染方法。

import React from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
    <App />
);

如果在React17的渲染方式中使用React18的功能,我认为会在控制台上显示如下错误。
如果出现此错误,请修改为使用createRoot()。

image.png

严格模式是什么?

在React18中,已添加了一个新功能,它被称为Strict模式,可以检测正在开发中的应用程序存在的问题。简单来说,Strict模式会将可能因为将来不再支持的功能或新功能而导致破坏的部分显示为警告信息。需要注意的是,该功能仅对开发服务器有影响,构建并部署到生产环境后,该功能将不再起作用。

关于此次新增的功能,我将从官方文档中提取相关内容。

React 18 将在严格模式下引入新的开发时专用检查。这个新的检查会在每次组件首次挂载时自动卸载和重新挂载所有组件,并在第二次挂载时恢复先前的状态。

可能需要重新表达,但它的意思是这样的:组件显示(挂载)→组件卸载(卸载)→再次组件显示(重新挂载)。

我们来看看它实际上会做什么样的动作。
创建一个App组件,在其中调用useEffect。

import React, { useEffect } from 'react';

function App() {
   useEffect(() => { 
     console.log('Strictモード確認');
   }, []);  
  return (
    <div className="App"></div>
  );
}

export default App;
image.png
image.png

我认为可以看出已经执行了装载⇒卸载⇒再次装载。

此功能的目的主要是为了为未来计划中的离屏API做准备。

离屏API是一种使用相同状态对树进行卸载和再装载,以实现快速屏幕显示的功能。

我们现在要着重设计,以便在离屏API实际实施时可以立即适应。

是否有一种方法可以将Strict模式关闭?

我认为通过选择React18,这个行为将自然地被添加,因此只能将注释掉。

自动分批

关于批处理,我将引用官方资料。

批处理是指React通过将多个状态更新分组并合并为单个重新呈现来提高性能。在自动批处理之前,只有在React事件处理程序中的更新才会进行批处理。promise、setTimeout、本机事件处理程序和其他所有事件中发生的更新默认情况下不进行批处理。

在React18之前,当在promise或setTimeout中更新状态时,每次更新都会触发重新渲染。
通过自动批处理,无论在promise或setTimeout中更新状态多少次,重新渲染只会发生一次。

实际操作如下。
由于使用API,我们将使用名为”json placeholder”的服务。

 

import { useState } from 'react';

type Todo = {
    "userId": number,
    "id": number,
    "title": string,
    "completed": boolean
}

export const AutoBatchOther = () => {
    console.log('レンダリングされてる!');
    const [todos, setTodos] = useState<Todo[] | null>(null);
    const [state2, setState2] = useState<string>('');

    const onClickExecutionApi = () => {
        fetch('https://jsonplaceholder.typicode.com/todos')
        .then((res) => res.json())
        .then((data) => {
            setTodos(data);
            setState2('updated');
        })
    }
    return (
        <div>
            <p>Automatic Batch確認</p>
            <button onClick={onClickExecutionApi}>API実行</button>
            {todos?.map((todo) => <p key={todo.id}>{todo.title}</p>)}
        </div>
    )
}
image.png
image.png

自动分批处理是无需特别意识到的实现方式,只需提升版本即可应用,无需修改源代码,而且还能提升性能,所以只有优点!

最后

我主要在Udemy上学习React,但是只是观看视频并编写代码却无法很快牢记,所以我需要实践并进行输出才能记住…由于我也是初学者,如果有任何错误之处,请指正。

参考文章

React 公式:仔细了解将成为未来前端开发必备知识的 React v18 的功能
用于测试的 API 服务器

广告
将在 10 秒后关闭
bannerAds