今天分享React的应用:介绍一些获取数据的方法。我们熟悉三种方法:使用生命周期方法请求数据和使用数据 Hooks 获取数据和使用 suspense 获取数据。接下来,让我们了解他们的应用程序和优缺点。
使用生命周期方法请求数据
应用程序Employees.org
做两件事:
1.一旦进入程序,就会得到它
20
名员工。
2.员工可以通过过滤条件进行筛选。
在实现这两个需求之前,让我们回顾一下React 类组件的2
生命周期方法:
componentDidMount()
:组件挂载后执行
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>在员工数据中获取...</div>; } return <EmployeesList employees={employees} />; } }
打开codesandbox可以查看 <EmployeesPage>
获取过程。
<EmployeesPage>
获取数据的异步方法有一种fetch()
。获取请求完成后使用 setState
方法来更新employees
。
this.fetch()
在componentDidMount()
实施生命周期方法:在组件初始渲染时获取员工数据。
当我们的关键字被过滤时,它将被更新 props.query
。每当 props.query
更新,componentDidUpdate()
它将被重新执行this.fetch()
。
虽然生命周期方法相对容易掌握,但基于类的方法很难重用样板代码。
优点
这种方法很容易理解:componentDidMount()
在第一次渲染中获取数据,componentDidUpdate()
在props
更新时重新获取数据。
缺点
样板代码:
基于类组件需要继承React.Component
,执行构造函数 super(props)
等等。
this
使用 this
关键字很麻烦。
代码重复
componentDidMount()
和componentDidUpdate()
大部分代码都是重复的。
很难重用
在另一个组件中很难重用员工获得的逻辑。
使用 Hooks 获取数据
Hooks 更好的选择是基于类获取数据的方式。作为一个简单的函数,Hooks 它不像类组件那样继承,而且更容易重用。
简单回忆一下useEffect(callback[, deps])
Hook 。这个hook挂载后执行callback
,而且作为依赖项deps
重新渲染发生变化时。
如下示例所示,在<EmployeesPage>
中使用useEffect()
获取员工数据:
import EmployeesList from "./EmployeesList"; import { fetchEmployees } from "./fake-fetch"; function EmployeesPage({ query }) { const [isFetching, setFetching] = useState(false); const [employees, setEmployees] = useState([]); useEffect(function fetch() { (async function() { setFetching(true); setEmployees(await fetchEmployees(query)); setFetching(false); })(); }, [query]); if (isFetching) { return <div>Fetching employees...</div>; } return <EmployeesList employees={employees} />; }
打开codesandbox可以查看useEffect()
如何获取数据。
可以看到使用 Hooks 的 <EmployeesPage>
比使用类组件简单多了。
在<EmployeesPage>
函数组件中的useEffect(fetch, [query])
,初始渲染后执行fetch
回调。另外,当依赖项目时。 query
更新时也会重新执行 fetch
方法。
但仍有优化的空间。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} />; }
从useEmployeesFetch()
提到所需的值。组件<EmployeesPage>
没有相应的获取逻辑,只负责渲染界面。
更好的是,它可以在需要获得员工的任何其他组件中重用useEmployeesFetch()
。
优点
清楚和简单
Hooks没有样板代码,因为它们是普通函数。
可重用性
在 Hooks 获取数据的逻辑很容易重用。
缺点需要预先知识
Hooks 有点违背直觉,所以使用前一定要理解,Hooks 依靠闭包,所以一定要很好地了解它们。
必要性
使用Hooks,仍然必须使用命令方法来执行数据获取。
使用 suspense 获取数据
Suspense
为异步获取React中的数据提供了一种声明方法。
注:截至2019年11月,Suspense 处于试验阶段。
<Suspense>
包装执行异步操作的组件:
<Suspense fallback={<span>Fetch in progress...</span>}> <FetchSomething /> </Suspense>
当数据获取时,Suspense
将显示fallback
获取数据后,中间的内容,Suspense
获取数据渲染的使用<FetchSomething />
。
我们来看看怎么用Suspense
:
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} />; }
打开codesandbox可以查看Suspense
如何获取数据。
<EmployeesPage>
使用Suspense
处理组件将获得数据并传递给<EmployeesFetch>
组件。
<EmployeesFetch>
中的resource.employees
是一种特殊的包装promise
,它在背后与Suspense
通信。这样,Suspense
就知道“挂”了。 <EmployeesFetch>
渲染需要多长时间,当资源准备就绪时,渲染工作就开始了。
最大的优点是:Suspense
异步操作是通过声明和同步来处理的。组件没有复杂的数据获取逻辑,而是通过声明来渲染内容。组件中没有生命周期,没有生命周期 Hooks,async/await
,没有回调:只显示界面。
优点
声明式
Suspense
在React中以声明的形式执行异步操作。
简单
声明代码使用起来很简单,这些组件没有复杂的数据获取逻辑。
实现松耦合和获取
使用Suspense
组件看不到如何获取数据:使用 REST 或 GraphQL。Suspense
设置边界,保护获取细节泄露到组件中。
标准状态
若要求多个获取操作,则Suspense
最新的获取请求将被使用。