React生命周期方法、hooks suspense获取数据的方式比较

本文对比了React中的生命周期方法、Hooks和Suspense在异步数据获取中的应用,探讨了各自的优缺点,包括减少样板代码、可重用性、声明式编程和对实现细节的隐藏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React中的生命周期方法,hooks, suspense获取数据的优缺点比较

在执行诸如数据提取之类的I / O操作时,您必须启动提取操作,等待响应,将响应数据保存到组件的状态,最后进行渲染。

异步数据获取需要付出额外的努力才能适应React的声明性。逐步改进React可以最大程度地减少这种额外的工作。

生命周期方法,hooks和suspense是在React中获取数据的方法。我将在示例和演示中对其进行描述,并比较出每个示例的优缺点。

了解每种方法的来龙去脉将使您更好地编码异步操作。

1.使用生命周期方法获取数据

应用程序Employees.org必须做两件事:

  1. 最初获取公司20名员工。
  2. 筛选名称包含查询的员工。

在实现这些要求之前,请回顾类组件的2个生命周期方法:

  1. componentDidMount():挂载只后执行一次
  2. componentDidUpdate(prevProps):在props或state改变时执行

<EmployeesPage> 使用以下两种生命周期方法实现提取逻辑:

import EmployeesList from "./EmployeesList";
import { fetchEmployees } from "./fake-fetch";

class EmployeesPage extends Component {
constructor(props) {
super(props);
this.state = { employees: [], isFetching: true };
}

componentDidMount() {
this.fetch();
}
componentDidUpdate(prevProps) {
if (prevProps.query !== this.props.query) {
this.fetch();
}
}
async fetch() {
this.setState({ isFetching: true });
const employees = await fetchEmployees(this.props.query);
this.setState({ employees, isFetching: false });
}

render() {
const { isFetching, employees } = this.state;
if (isFetching) {
return <div>Fetching employees....</div>;
}
return <EmployeesList employees={employees} />;
}
}

<EmployeesPage>有一个fetch()处理获取的异步方法。提取请求完成后,组件状态将更新为fetched employees

this.fetch()componentDidMount()生命周期方法中执行:最初呈现组件时,这开始获取员工。

当用户在输入字段中输入查询时,props 上query会更新。每次发生时,this.fetch()均由componentDidUpdate()执行,以实现对员工的过滤。

尽管生命周期方法相对容易掌握,但是基于类的方法却遇到了样板代码和可重用性的难题。

好处

直观
易懂:生命周期方法会componentDidMount()在首次渲染componentDidUpdate()时启动获取,并在props更改时重新获取数据。

缺点

基于类的组件需要“仪式”代码:继承React.Componentsuper(props)在内部调用constructor()等。

this
使用this关键字很麻烦。

重复代码
里面的代码componentDidMount()componentDidUpdate()大部分重复。

难以复用
员工获取逻辑很难在另一个组件中复用。

2.使用hooks获取数据

hooks是基于类的获取的更好的替代方法。作为简单的函数,hooks没有“仪式”代码,并且更易于重用。

让我们回想一下useEffect(callback[, deps])函数。该回调callback函数在挂载后以及deps更改后渲染执行。

在以下示例中<EmployeesPage>用于useEffect()获取员工数据:

<EmployeesPage>使用hooks简化了很多。

内部<EmployeesPage>功能组件在初始渲染后,useEffect(fetch, [query])执行fetch回调。此外,fetch在稍后渲染之后会被调用,仅当props属性上的query更改时才被调用。

hooks允许你从组件中提取员工获取逻辑<EmployeesPage>。让我们这样做:

import React, { useState } from 'react';

import EmployeesList from "./EmployeesList";
import { fetchEmployees } from "./fake-fetch";

function useEmployeesFetch(query) {
const [isFetching, setFetching] = useState(false);
const [employees, setEmployees] = useState([]);

useEffect(function fetch {
(async function() {
setFetching(true);
setEmployees(await fetchEmployees(query));
setFetching(false);
})();
}, [query]);

return [isFetching, employees];
}

function EmployeesPage({ query }) {
const [employees, isFetching] = useEmployeesFetch(query);
if (isFetching) {
return <div>Fetching employees....</div>;
}
return <EmployeesList employees={employees} />;
}

该组件<EmployeesPage>不会因获取逻辑而杂乱无章,而是直接完成了工作:渲染UI元素。

更好的是,您可以useEmployeesFetch()在需要获取员工的任何其他组件中重用。

好处


hooks简单钩子没有样板代码,因为它们是普通函数。

可重用性
在hooks中实现的获取逻辑易于重用。

缺点

hooks在一定程度上是违反直觉的,因此在使用之前必须先了解它们。hooks依赖于封闭,因此请一定非常了解它们

对于钩子,您仍然必须使用命令式方法来执行数据提取。

3.使用suspense获取数据

Suspense提供了一种声明式方法来在React中异步获取数据。

注意:截至2019年11月,暂停处于试验阶段。

<Suspense> 包装执行异步操作的组件:

<Suspense fallback={<span>Fetch in progress...</span>}>
<FetchSomething />
</Suspense>

进行抓取时,suspense将呈现fallback内容。稍后,当获取完成时,将<FetchSomething />使用获取的数据进行暂挂渲染。

让我们看看员工的申请是如何悬而未决的:

import React, { Suspense } from "react";
import EmployeesList from "./EmployeesList";

function EmployeesPage({ resource }) {
return (
<Suspense fallback={<h1>Fetching employees....</h1>}> <EmployeesFetch resource={resource} /> </Suspense> );
}

function EmployeesFetch({ resource }) {
const employees = resource.employees.read();
return <EmployeesList employees={employees} />;
}

<EmployeesPage>使用suspense处理内部提取组件<EmployeesFetch>

resource.employees内部<EmployeesFetch>是一个特别包装的承诺,在后台与suspense进行了交流。通过这种方式,Suspense可以知道“”渲染的“挂起”时间<EmployeesFetch>,以及资源准备就绪后的时间。

这是一个巨大的胜利:Suspense以声明性和同步方式处理异步操作

这些组件不会杂乱如何获取数据的详细信息。而是它们以声明方式使用资源来呈现内容。async/await组件内部没有生命周期,没有hooks,也没有回调:仅呈现资源。

好处

声明式
挂起允许您在React中声明式执行异步操作。

简单性
声明性代码易于使用。这些组件不会杂乱如何获取数据的详细信息。

与获取实现
松耦合使用suspense的组件不知道如何获取数据:使用REST或GraphQL。暂挂设置了一个边界,该边界可保护获取的详细信息泄漏到您的组件中。

无竞争条件
如果启动了多个提取操作,则暂挂将使用最新的提取请求。

缺点


需要挂起需要专门的提取库或实现挂起获取接口的适配器。

4.关键要点

长期以来,生命周期方法一直是获取数据的唯一解决方案。但是,使用它们进行获取存在许多样板代码,重复和可重用性困难的问题。

使用hooks获取是更好的选择:减少样板代码。

Suspense的好处是声明式获取。您的组件不会因获取实现细节而混乱。Suspense更接近于React本身的声明性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值