ReactJS - 使用 React 钩子的组件生命周期



React Hooks 提供了一个特殊的 Hook,useEffect() 来在组件的生命周期中执行某些功能。useEffect() 将 componentDidMount、componentDidUpdate 和 componentWillUnmount 生命周期合并到一个 API 中。

useEffect() api 的签名如下: -


useEffect(
	 	<executeFn>,	
	 	<values>
);

这里

  • executeFn - 当效果发生时执行的函数,带有可选的返回函数。当需要清理时,将执行返回函数(类似于 componentWillUnmount)。
  • values − 效果所依赖的值数组。React Hooks 仅在值更改时执行 executeFn。这将减少对 executeFn 的不必要调用。

让我们在 react-clock-hook-app 应用程序中添加 useEffect() 钩子。

在你最喜欢的编辑器中打开 react-clock-hook-app。

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

接下来,导入 useEffect api。


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

接下来,使用函数调用 useEffect,使用 setInterval 设置每秒的日期和时间,并使用 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 接口,每秒停止执行 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 ReactDOM from 'react-dom';
import Clock from './components/Clock';

ReactDOM.render(
	 	<React.StrictMode>
	 	 	 <Clock />
	 	</React.StrictMode>,
	 	document.getElementById('root')
);
setTimeout(() => {
	 	ReactDOM.render(
	 	 	 <React.StrictMode>
	 	 	 	 	<div><p>Clock is removed from the DOM.</p></div>
	 	 	 </React.StrictMode>,
	 	 	 document.getElementById('root')
	 	);
}, 5000);

接下来,使用 npm 命令为应用程序提供服务。

npm start

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

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

Cleanup Code

React 子属性又名 Containment

React 允许在组件中包含任意子用户界面内容。可以通过 this.props.children 访问组件的子项。在组件内添加子项称为包含。在组件的某些部分本质上是动态的情况下使用封闭。

例如,富文本消息框在被调用之前可能不知道其内容。让我们创建 RichTextMessage 组件来展示本章中 React 子属性的特性。

首先,按照创建 React 应用程序一章中的说明,使用 Create React App 或 Rollup bundler 创建一个新的 react 应用程序 react-message-app。

接下来,在您最喜欢的编辑器中打开应用程序。

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

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

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

接下来,导入 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;

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


import React from 'react';
import ReactDOM from 'react-dom';
import RichTextMessage from './components/RichTextMessage';

ReactDOM.render(
	 	<React.StrictMode>
	 	 	 <RichTextMessage>
	 	 	 	 	<h1>Containment is really a cool feature.</h1>
	 	 	 </RichTextMessage>
	 	</React.StrictMode>,
	 	document.getElementById('root')
);

最后,在根文件夹下创建一个公共文件夹,并创建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 ReactDOM from 'react-dom';
import Clock from './components/Clock';

ReactDOM.render(
	 <React.StrictMode>
	 	 	 	 	<RichTextMessage>
	 	 	 	 	 	 <h1>Containment is really an excellent feature.</h1>
	 	 	 	 	</RichTextMessage>
	 	</React.StrictMode>,
	 	document.getElementById('root')
);

现在,浏览器会更新组件的子内容并发出,如下所示 -


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

简而言之,包含是将任意用户界面内容传递给组件的绝佳功能。