React Hooks 怎么实现组件生命周期?

文章导读
Previous Quiz Next React Hooks 提供了一个特殊的 Hook,即 useEffect(),用于在组件生命周期中执行特定功能。useEffect() 将 componentDidMount、componentDidUpdate 和 component
📋 目录
  1. React children 属性(又称 Containment)
A A

使用 React Hooks 的组件生命周期



Previous
Quiz
Next

React Hooks 提供了一个特殊的 Hook,即 useEffect(),用于在组件生命周期中执行特定功能。useEffect()componentDidMountcomponentDidUpdatecomponentWillUnmount 生命周期方法合并为一个单一的 API。

useEffect() API 的签名如下 −

useEffect(
   <executeFn>, 
   <values>
);

其中,

  • executeFn − 当 effect 发生时执行的函数,并带有可选的返回函数。该返回函数将在需要清理时执行(类似于 componentWillUnmount)。

  • values − effect 所依赖的值数组。React Hooks 仅在这些值发生变化时才执行 executeFn。这可以减少不必要的 executeFn 调用。

让我们在 react-clock-hook-app 应用中添加 useEffect() Hook。

在您喜欢的编辑器中打开 react-clock-hook-app

接下来,打开 src/components/Clock.js 文件并开始编辑。

接下来,导入 useEffect API。

import React, { useState, useEffect } from 'react';

接下来,使用 setInterval 调用 useEffect,每秒设置一次日期和时间,并返回一个函数,使用 clearInterval 停止更新日期和时间。

useEffect(
   () => {
      let setTime = () => {
         console.log("setTime is called");
         setCurrentDateTime(new Date());
      }
      let interval = setInterval(setTime, 1000);
      return () => {
         clearInterval(interval);
      }
   },
   []
);

其中,

  • 创建了一个函数 setTime,用于将当前时间设置到组件的状态中。

  • 调用了 setInterval JavaScript API,每秒执行一次 setTime,并将 setInterval 的引用存储在 interval 变量中。

  • 创建了一个返回函数,该函数调用 clearInterval API,通过传递 interval 引用来停止每秒执行 setTime

现在,我们已经更新了 Clock 组件,组件的完整源代码如下 −

import React, { useState, useEffect } from 'react';

function Clock() {
   const [currentDateTime, setCurrentDateTime] = useState(new Date());
   useEffect(
      () => {
         let setTime = () => {
            console.log("setTime is called");
            setCurrentDateTime(new Date());
         }
         let interval = setInterval(setTime, 1000);
         return () => {
            clearInterval(interval);
         }
      },
      []
   );
   return (
      <div>
         <p>The current time is {currentDateTime.toString()}</p>
      </div>
   );
}
export default Clock;

接下来,打开 index.js,并使用 setTimeout 在 5 秒后从 DOM 中移除时钟。

import React from 'react';
import { createRoot } from 'react-dom/client';
import Clock from './components/Clock'


const container = document.getElementById('root');
const root = createRoot(container);
root.render(<Clock />);

setTimeout(() => {
   root.render(<div><p>Clock is removed from the DOM.</p></div>);
}, 5000);

接下来,使用 npm 命令启动应用。

npm start

接下来,打开浏览器,在地址栏输入 http://localhost:3000 并按回车。

时钟将显示 5 秒,然后从 DOM 中移除。通过查看控制台日志,我们可以发现清理代码被正确执行。

Cleanup Code

React children 属性(又称 Containment)

React 允许在组件内部包含任意的子用户界面内容。可以通过 this.props.children 访问组件的子元素。在组件内部添加子元素称为 containmentContainment 用于组件的某些部分具有动态性质的情况。

例如,富文本消息框在被调用时可能还不知道其内容。在本章中,我们将创建一个 RichTextMessage 组件来展示 React children 属性的功能。

首先,使用 Create React AppRollup bundler,按照 Creating a React application 章节的说明创建一个新的 React 应用 react-message-app

接下来,在你喜欢的编辑器中打开该应用。

接下来,在应用根目录下创建 src 文件夹。

接下来,在 src 文件夹下创建 components 文件夹。

接下来,在 src/components 文件夹下创建一个文件 RichTextMessage.js,并开始编辑。

接下来,导入 React 库。

import React from 'react';

接下来,创建一个类 RichTextMessage,并使用 props 调用构造函数。

class RichTextMessage extends React.Component {
   constructor(props) { 
      super(props); 
   } 
}

接下来,添加 render() 方法,并显示组件的用户界面及其子元素。

render() { 
   return ( 
      <div>{this.props.children}</div> 
   ) 
}

这里:

  • props.children 返回组件的子元素。

  • 将子元素包装在 div 标签内。

最后,导出该组件。

export default RichTextMessage;

RichTextMessage 组件的完整源代码如下所示 −

import React from 'react';

class RichTextMessage extends React.Component {
   constructor(props) {
      super(props);
   }
   render() {
      return (
         <div>{this.props.children}</div>
      )
   }
}
export default RichTextMessage;

接下来,在 src 文件夹下创建一个文件 index.js,并使用 RichTextMessage 组件。

import React from 'react';
import { createRoot } from 'react-dom/client';
import RichTextMessage from './components/RichTextMessage'

const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<RichTextMessage>
   <h1>Containment is really a cool feature.</h1>
</RichTextMessage>
);

最后,在根文件夹下创建一个 public 文件夹,并创建 index.html 文件。

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <title>React App</title>
   </head>
   <body>
      <div id="root"></div>
      <script type="text/JavaScript" src="./index.js"></script>
   </body>
</html>

接下来,使用 npm 命令启动应用。

npm start

接下来,打开浏览器,在地址栏输入 http://localhost:3000 并按回车。

Cleanup Codes

浏览器会将组件的子元素包装在 div 标签中输出,如下所示 −

<div id="root">
   <div>
      <div>
         <h1>Containment is really a cool feature.</h1>
      </div>
   </div>
</div>

接下来,在 index.js 中更改 RichTextMessage 组件的子元素属性。

import React from 'react';
import { createRoot } from 'react-dom/client';
import RichTextMessage from './components/RichTextMessage'

const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<RichTextMessage>
   <h1>Containment is really an excellent feature.</h1>
</RichTextMessage>
);

现在,浏览器会更新组件的子元素内容并输出如下所示 −

<div id="root">
    <div>
        <div>
            <h1>Containment is really an excellent feature.</h1>
        </div>
    </div>
</div>

简而言之,containment 是一个将任意用户界面内容传递给组件的优秀特性。