【React】Strict模式的行为【基于版本18】

首先

2022年3月29日,React发布了18版。

由于本公司从6月份开始举办React新功能研讨会,所以我打算这次就顺便整理一下范围之外的内容,以便预习研讨会的范围。

由於React 18中StrictMode的行為已經升級,因此本次將對其進行解釋。

严格模式是什么意思?

从MDN引用如下

JavaScript 的 Strict 是一种使用 JavaScript 限制变体的方法,通过它可以隐式地停止 “sloppy mode”。严格模式不仅仅是一个子集,它有意地具有与常规代码不同的含义。

简单来说,它是一种能够比通常更严格地检查JavaScript代码的机制。

作为优点

    • 将来の ECMAScript で予定されている構文(キーワードを変数名として使用するなど) を禁止して、バージョンが変わった後の動作を修正を無くことができる。

 

    Javascriptの構文としてはエラーにはならないが、バグを誘発するようなコードを検出することができる

可以列举如下等等的例子。

在React18中,严格模式的新行为。

从以下的React公式中引用

未来我们希望引入一个功能,能够在保持React的状态的同时,添加或删除UI的一部分。
这个功能将提高React在标准状态下的性能,但需要组件对多次注册和销毁副作用具有耐受性。大多数副作用会在没有任何更改的情况下正常工作,但一些副作用被假定为只注册和销毁一次。
为了更容易发现这个问题,React 18将在严格模式下引入新的开发时检查。这个新的检查将在每次组件首次挂载时自动卸载和重新挂载所有组件,并在第二次挂载时恢复先前的状态。

如果你是一个很快就能理解的人,也许会说:“完全理解了!” 不过,因为我自己脑中并不清晰,所以我用实际的代码进行了验证。

这次我们将使用React17和React18的代码来查看其操作方式!

React17的行为

请跟着以下的文章,进行React 17的环境设置!

 

请在环境设置完成后将以下代码写入src/App.tsx文件中。

import { useEffect } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  console.log('App rendered!')

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
スクリーンショット 2023-06-18 23.57.17.png

我认为你可以从上面的截图中看出来,App组件只渲染了一次!

React18的行为

请将相同的代码写在src/App.tsx中。

如果这样做的话…

スクリーンショット 2023-06-19 0.11.43.png

在这段文字中,我认为可以这样翻译成中文:

App 渲染!这句话重复出现了两次,说明 App 组件渲染了两次。
在 React18 中,组件在显示的瞬间会被销毁一次,然后立即重新显示,这类似于在背后进行的动作。

为什么要进行这种看似无意义的动作呢?原因是考虑到未来React的功能增加。

据说会添加一个名为”Offscreen”的功能。类似于标签切换,可以从屏幕上转到另一个界面,然后再返回原始界面并恢复状态,通过恢复状态来更快地让用户使用应用程序。这样的机制将提供给用户更高效的使用体验。

由于上述解释,应用程序在离屏(offsereen)上会重新挂载,因此React18的Stric模式下会进行两次渲染。

想要将 Strict 模式关闭的话,可以…?

请删除src/index.tsx中的以下部分。

import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

这样做的话,就会像React17之前一样只进行一次渲染。

此外,在严格模式下只适用于开发环境,
请记住在生产环境中只进行一次渲染!

最后

尽可能在开发React应用时启用Strict模式并重新挂载应用,以确保在开发环境中不会出现问题,我认为这将成为未来React开发中的重要方向。

如果这次内容的反响好的话,我就考虑再发一篇关于React18新功能的文章。

如果这篇文章对于正在学习React 18的人有所帮助,我会非常高兴!

文献和视频参考资料

    • 今後のフロントエンド開発で必須知識となるReact v18の機能を丁寧に理解する

 

    • React v18.0 公式

 

    • MDN 厳格モード

 

    (初心者向け) JavaScript の Strict モードの概要
广告
将在 10 秒后关闭
bannerAds