30天入坑React ---------------day07 Lifecycle Hooks

react

这篇文章是30天React系列的一部分 。

在本系列中,我们将从非常基础开始,逐步了解您需要了解的所有内容,以便开始使用React。如果您曾经想学习React,那么这里就是您的最佳选择!

下载免费的PDF

生命周期钩子

在Github上编辑此页面

今天,我们将介绍一些我们可以与React组件一起使用的最常见的生命周期钩子,我们将讨论它们为什么有用以及何时应该使用它们。

恭喜!我们已经在React的第一周结束了,我们已经覆盖了很多。我们刚刚完成了有状态组件的工作,以跟踪组件的内部状态。今天,我们将暂停实现,并谈谈组件如何存在于应用程序中。也就是说,我们将讨论组件的生命周期。

当React安装我们的应用程序时,它为我们提供了一些钩子,我们可以在组件的生命周期中的不同时间插入我们自己的功能。为了挂钩生命周期,我们需要在我们的组件上定义函数,React在适当的时候调用每个钩子。让我们深入了解第一个生命周期钩子:

componentWillMount() / componentDidMount()

当在我们的应用程序的页面上定义组件时,我们不能立即依赖它在DOM中可用,因为我们正在定义虚拟节点。相反,我们必须等到组件本身实际安装在浏览器中。对于我们在安装时需要运行的功能,我们可以获得两个不同的钩子(或函数)。在组件之前调用的一个是在页面上安装的,另一个是在组件安装之后调用的。

什么mounting意思?

由于我们使用React在DOM树中定义节点的虚拟表示,我们实际上并没有定义DOM节点。相反,我们正在建立React为我们维护和管理的内存视图。当我们谈论安装时,我们讨论的是将虚拟组件转换为React放置在DOM中的实际DOM元素的过程。

这对于诸如获取数据以填充组件之类的内容非常有用。例如,假设我们想要使用我们的活动跟踪器来显示github事件。我们只想在要呈现数据本身时加载这些事件。

回想一下,我们Content在活动列表中定义了我们的组件:

class Content extends React.Component {

render() {

const {activities} = this.props; // ES6 destructuring

return (

<div className="content">

<div className="line"></div>

{/* Timeline item */}

{activities.map((activity) => (

<ActivityItem

activity={activity} />

))}

</div>

)

}

}

让我们更新Content组件以向github.com事件api发出请求,并使用响应来显示活动。因此,我们需要更新state对象。

正如我们昨天所做的那样,让我们 通过设置this.state构造函数中的对象来更新我们的组件是有状态的

class Content extends React.Component {

constructor(props) {

super(props);

this.state = {

activities: []

}

}

// ...

}

现在,我们将要在组件本身准备好安装时(或者在安装之后)发出HTTP请求。通过在我们的组件中定义函数componentWillMount()(或componentDidMount()),React在它安装到DOM之前运行该方法。这是我们添加GET请求的最佳位置。

让我们Content用github api的请求更新组件。由于我们只想显示一个小列表,让我们来看看最新的四个事件。

我们已经存储了一个github数据的静态JSON文件,我们将直接从源码加载(我们将在几天后回到发出AJAX请求)使用promises。现在,让我们关注如何使用新数据实现更新组件:

class Content extends React.Component {

// ...

componentWillMount() {

this.setState({activities: data});

}

// ...

}

请注意,我们没有更改Content组件中的任何其他内容,它只是起作用。

componentWillUpdate() / componentDidUpdate()

有时我们会在更改实际渲染之前或之后更新组件的某些数据。例如,假设我们想调用一个函数来设置渲染,或者在组件的props改变时调用一个函数集。该componentWillUpdate()方法是一个合理的钩子来处理准备我们的组件进行更改(只要我们不调用this.setState()它来处理它,因为它会导致无限循环)。

由于我们不需要深入处理这个问题,我们不会担心在这里建立一个例子,但知道它存在是很好的。我们将使用的一个更常见的生命周期钩子是componentWillReceiveProps()钩子。

componentWillReceiveProps()

当组件即将接收新的时,React将调用方法props。这是第一个在组件要接收一组新道具时调用的方法。定义此方法是查找特定更新的好时机,props因为它使我们有机会计算更改并更新组件的内部状态。

这是我们可以根据新道具更新状态的时间。

这里要记住的一件事是,即使componentWillReceiveProps()调用该方法,它的值props也可能没有改变。它总是以检查道具值的变化是一个好主意。

例如,让我们在活动列表中添加一个刷新按钮,这样我们的用户就可以请求重新请求github事件api。

我们将使用componentWillReceiveProps()钩子来请求组件重新加载它的数据。由于我们的组件是有状态的,我们将希望用新数据刷新此状态,因此我们不能简单地更新props组件。我们可以使用该componentWillReceiveProps()方法告诉我们想要刷新的组件。

让我们在包含元素上添加一个按钮,该按钮传递一个requestRefresh布尔值,告诉Content组件刷新。

class Container extends React.Component {

constructor(props) {

super(props);

this.state = {refreshing: false}

}

// Bound to the refresh button

refresh() {

this.setState({refreshing: true})

}

// Callback from the `Content` component

onComponentRefresh() {

this.setState({refreshing: false});

}

render() {

const {refreshing} = this.state;

return (

<div className='notificationsFrame'>

<div className='panel'>

<Header title="Github activity" />

{/* refreshing is the component's state */}

<Content

onComponentRefresh={this.onComponentRefresh.bind(this)}

requestRefresh={refreshing}

fetchData={fetchEvents} />

{/* A container for styling */}

<Footer>

<button onClick={this.refresh.bind(this)}>

<i className="fa fa-refresh" />

Refresh

</button>

</Footer>

</div>

</div>

)

}

}

<Footer />

请注意,我们在这里有一个新元素,用于显示元素的子元素。这是一种允许我们在某些内容周围添加CSS类的模式。

class Footer extends React.Component {

render() {

return (

<div className='footer'>

{this.props.children}

</div>

)

}

}

使用这个新的proprequestRefreshprop),我们可以在更改值时更新activities我们的state对象。

class Content extends React.Component {

// ...

componentWillReceiveProps(nextProps) {

// Check to see if the requestRefresh prop has changed

if (nextProps.requestRefresh !== this.props.requestRefresh) {

this.setState({loading: true}, this.updateData);

}

}

// ...

}

时间

此演示使用来自JSON文件的静态数据,并在刷新时随机选取四个元素。这是为了模拟刷新而设置的。

componentWillUnmount()

在卸载组件之前,React将调用componentWillUnmount()回调。这是处理我们可能需要的任何清理事件的时间,例如清除超时,清除数据,断开websockets等。

例如,我们上次使用的时钟组件,我们设置每秒调用一次超时。当组件准备好卸载时,我们希望确保清除此超时,以便我们的JavaScript不会继续为实际不存在的组件运行超时。

回想一下,timer我们构建的组件如下所示:

class Clock extends React.Component {

constructor(props) {

super(props);

this.state = this.getTime();

}

componentDidMount() {

this.setTimer();

}

setTimer() {

this.timeout = setTimeout(this.updateClock.bind(this), 1000);

}

updateClock() {

this.setState(this.getTime, this.setTimer);

}

getTime() {

const currentTime = new Date();

return {

hours: currentTime.getHours(),

minutes: currentTime.getMinutes(),

seconds: currentTime.getSeconds(),

ampm: currentTime.getHours() >= 12 ? 'pm' : 'am'

}

}

// ...

render() {

}

}

当我们的时钟将被卸载时,我们将要清除我们在setTimer()组件上的函数中创建的超时。添加该componentWillUnmount()功能可以完成这种必要的清理工作。

class Clock extends React.Component {

// ...

componentWillUnmount() {

if (this.timeout) {

clearTimeout(this.timeout);

}

}

// ...

}

12 :52:01 日下午

这些是我们可以在React框架中与之交互的一些生命周期钩子。在构建我们的反应应用程序时,我们会使用这些,因此熟悉它们,它们存在以及如何挂钩组件的生命是一个好主意。

我们确实在这篇文章中引入了一个新概念,我们在其中添加了一个回调函数:我们在一个要从子进程调用的组件上添加了一个回调函数。在下一节中,我们将讨论如何定义和记录prop组件的API,以便在跨团队和应用程序共享组件时使用。

学习REACT正确的方法

React和朋友的最新,深入,完整的指南。

下载第一章

❮上一个

下一章:

包装和PropTypes

下一个 ❯

本教程系列的完整源代码可以在GitHub repo上找到,其中包括所有样式和代码示例。

如果您在任何时候感到困难,还有其他问题,请随时通过以下方式与我们联系:

  • 在文章末尾评论这篇文章
  • 通过[email protected]发送电子邮件给我们
  • 加入我们的gitter室
  • 发送电子邮件至@fullstackreact

以上是 30天入坑React ---------------day07 Lifecycle Hooks 的全部内容, 来源链接: utcz.com/z/382867.html

回到顶部