ReactJS 教程

ReactJS 主页 ReactJS 简介 ReactJS 路线图 ReactJS 下载安装和环境配置 ReactJS 功能 ReactJS 优势和缺点 ReactJS 架构 ReactJS 创建 React 应用程序 ReactJS JSX ReactJS 组件 ReactJS 嵌套组件 ReactJS 使用组件 ReactJS 集合组件 ReactJS 样式 ReactJS 属性 (props) ReactJS 使用属性创建组件 ReactJS props 验证 ReactJS 构造函数 ReactJS 组件生命周期 ReactJS 事件管理 ReactJS 创建事件感知组件 ReactJS Expense Manager 事件 ReactJS 状态管理 ReactJS 状态管理 API ReactJS 无状态组件 ReactJS Hooks 进行状态管理 ReactJS Hooks 的组件生命周期 ReactJS 布局组件 ReactJS 分页 ReactJS Material UI ReactJS Http 客户端编程 ReactJS 表单编程 ReactJS 受控组件 ReactJS 非受控组件 ReactJS Formik ReactJS 条件渲染 ReactJS 列表 ReactJS Key 键 ReactJS 路由 ReactJS Redux ReactJS 动画 ReactJS Bootstrap ReactJS Map ReactJS 表格 ReactJS 使用 Flux 管理状态 ReactJS 测试 ReactJS CLI 命令 ReactJS 构建和部署 ReactJS 示例

Hooks

ReactJS Hooks 简介 ReactJS 使用 useState ReactJS 使用 useEffect ReactJS 使用 useContext ReactJS 使用 useRef ReactJS 使用 useReducer ReactJS 使用 useCallback ReactJS 使用 useMemo ReactJS 自定义 Hooks

ReactJS 高级

ReactJS 可访问性 ReactJS 代码拆分 ReactJS 上下文 ReactJS 错误边界 ReactJS 转发 Refs ReactJS 片段 ReactJS 高阶组件 ReactJS 与其他库集成 ReactJS 优化性能 ReactJS Profiler API ReactJS Portals ReactJS 不使用 ES6 ECMAScript ReactJS 不使用 JSX 的 React ReactJS Reconciliation ReactJS Refs 和 DOM ReactJS 渲染道具 ReactJS 静态类型检查 ReactJS 严格模式 ReactJS Web 组件

其他概念

ReactJS 日期选择器 ReactJS Helmet ReactJS 内联样式 ReactJS PropTypes ReactJS BrowserRouter ReactJS DOM ReactJS 轮播 ReactJS 图标 ReactJS 表单组件 ReactJS 参考 API

ReactJS 有用资源

ReactJS 快速指南 ReactJS 备忘录 Axios 备忘录 ReactJS 有用资源 ReactJS 讨论


ReactJS - 组件生命周期

在 React 中,组件的生命周期表示组件存在期间的不同阶段。React 提供回调函数来在 React 生命周期的每个阶段附加功能。让我们在本章中学习 React 组件的生命周期(和相关 API)。

生命周期 API

每个 React 组件都有三个不同的阶段。

  • 挂载 − 挂载表示在给定的 DOM 节点中渲染 React 组件。

  • 更新 − 更新表示在状态更改/更新期间在给定的 DOM 节点中重新渲染 React 组件。

  • 卸载 −卸载表示移除 React 组件。

React 提供了一组生命周期事件(或回调 API)来附加功能,这些功能将在组件的各个阶段执行。生命周期的可视化以及生命周期事件(API)的调用顺序如下所示。

Life Cycle

constructor() − 在 React 组件的初始构造阶段调用。用于设置组件的初始状态和属性。

render() − 在组件构造完成后调用。它在虚拟 DOM 实例中渲染组件。这被指定为在 DOM 树中安装组件。

componentDidMount() −在 DOM 树中初始安装组件后调用。这是调用 API 端点和执行网络请求的最佳位置。在我们的时钟组件中,可以在此处设置 setInterval 函数以每秒更新状态(当前日期和时间)。

componentDidMount() { 
   this.timeFn = setInterval( () => this.setTime(), 1000); 
}

componentDidUpdate() − 与 ComponentDidMount() 类似,但在更新阶段调用。此阶段可以进行网络请求,但前提是组件的当前属性和先前属性存在差异。

API 的签名如下 −

componentDidUpdate(prevProps, prevState, snap)
  • prevProps − 组件的先前属性。

  • prevState − 组件的先前状态。

  • snapshot − 当前渲染的内容。

componentWillUnmount() −组件从 DOM 卸载后调用。这是清理对象的好地方。在我们的时钟示例中,我们可以在此阶段停止更新日期和时间。

componentDidMount() { 
   this.timeFn = setInterval( () => this.setTime(), 1000); 
}

shouldComponentUpdate() − 在更新阶段调用。用于指定组件是否应更新。如果返回 false,则不会发生更新。

签名如下 −

shouldComponentUpdate(nextProps, nextState)
  • nextProps − 组件的即将出现的属性

  • nextState − 组件的即将出现的状态

getDerivedStateFromProps − 在初始和更新阶段以及 render() 方法之前调用。它返回新的状态对象。在属性更改导致状态更改的情况下很少使用它。它主要用于动画上下文中,其中需要组件的各种状态来实现流畅的动画。

API 的签名如下 −

static getDerivedStateFromProps(props, state)
  • props − 组件的当前属性

  • state − 组件的当前状态

这是一个静态方法,无法访问 this 对象。

getSnapshotBeforeUpdate − 在渲染内容提交到 DOM 树之前调用。它主要用于获取有关新内容的一些信息。此方法返回的数据将传递给 ComponentDidUpdate() 方法。例如,它用于维护用户在新生成的内容中的滚动位置。它返回用户的滚动位置。此滚动位置由componentDidUpdate()用于设置输出在实际DOM中的滚动位置。

API的签名如下 −

getSnapshotBeforeUpdate(prevProps, prevState)
  • prevProps − 组件的先前属性。

  • prevState − 组件的先前状态。

生命周期API的工作示例

让我们在我们的react-clock-app应用程序中使用生命周期API。

步骤1 −在您最喜欢的编辑器中打开 react-clock-hook-app。

打开 src/components/Clock.js 文件并开始编辑。

步骤 2 − 从构造函数中删除 setInterval() 方法。

constructor(props) { 
   super(props); 
   this.state = { 
      date: new Date() 
   } 
}

步骤 3 − 添加 componentDidMount() 方法并调用 setInterval() 每秒更新日期和时间。此外,存储引用以便稍后停止更新日期和时间。

componentDidMount() {
    this.setTimeRef = setInterval(() => this.setTime(), 1000);
}

添加 componentWillUnmount() 方法并调用 clearInterval() 以停止日期和时间更新调用。

componentWillUnmount() {
    clearInterval(this.setTimeRef)
}

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

import React from 'react';

class Clock extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
         date: new Date()
      }      
   }
   componentDidMount() {
      this.setTimeRef = setInterval(() => this.setTime(), 1000); 
   }
   componentWillUnmount() {
      clearInterval(this.setTimeRef)
   }
   setTime() {
      this.setState((state, props) => {
         console.log(state.date);
         return {
            date: new Date()
         }
      })
   }
   render() {
      return (
         <div>
            <p>The current time is {this.state.date.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 并按 Enter。

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

Interface DOM

Expense Manager(费用管理器)应用程序中的生命周期 API

让我们在Expense Manager(费用管理器)中添加生命周期 API,并在调用该 API 时记录它。这将提供有关组件生命周期的见解。

步骤 1 −在您最喜欢的编辑器中打开 expense-manager 应用程序。

接下来,使用以下方法更新 ExpenseEntryItemList 组件。

componentDidMount() {
   console.log("ExpenseEntryItemList :: Initialize :: componentDidMount :: Component mounted");
}
shouldComponentUpdate(nextProps, nextState) {
   console.log("ExpenseEntryItemList :: Update :: shouldComponentUpdate invoked :: Before update");
   return true;
}
static getDerivedStateFromProps(props, state) {
   console.log("ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update");
   return null;
}
getSnapshotBeforeUpdate(prevProps, prevState) {
   console.log("ExpenseEntryItemList :: Update :: getSnapshotBeforeUpdate :: Before update");
   return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
   console.log("ExpenseEntryItemList :: Update :: componentDidUpdate :: Component updated");
}
componentWillUnmount() {
   console.log("ExpenseEntryItemList :: Remove :: componentWillUnmount :: Component unmounted");
}

步骤 2 − 使用 npm 命令为应用程序提供服务。

npm start

打开浏览器并在地址栏中输入 http://localhost:3000 并按 Enter。

接下来,检查控制台日志。它将显示初始化阶段的生命周期 api,如下所示。

ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update 
ExpenseEntryItemList :: Initialize :: componentDidMount :: Component mounted

删除一个项目,然后检查控制台日志。它将显示更新阶段的生命周期 api,如下所示。

ExpenseEntryItemList :: Initialize / Update :: getDerivedStateFromProps :: Before update 
ExpenseEntryItemList.js:109 ExpenseEntryItemList :: Update :: shouldComponentUpdate invoked :: Before update 
ExpenseEntryItemList.js:121 ExpenseEntryItemList :: Update :: getSnapshotBeforeUpdate :: Before update 
ExpenseEntryItemList.js:127 ExpenseEntryItemList :: Update :: componentDidUpdate :: Component updated

最后,删除所有生命周期 API,因为它们可能会影响应用程序性能。只有在情况需要时才应使用生命周期 API。