We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
作者:Dmitri Pavlutin 译者:前端小智 来源:dmitripavlutin.com
阿里云最近在做活动,低至2折,真心觉得很划算了,可以点击本条内容或者链接进行参与: https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
为了保证的可读性,本文采用意译而非直译。
在执行 I/O 操作(例如数据提取)时,要先发送网络请求,然后等待响应,接着将响应数据保存到组件的状态,最后进行渲染。
在 React 中生命周期方法、Hooks和 Suspense是获取数据的方法。接下用事例演示一下如何使用它们并说明每种方法的优点和缺点,以便咱们更好的编写异步操作代码。
应用程序Employees.org做两件事:
Employees.org
1.一进入程序就获取20名员工。 2.可以通过过滤条件来筛选员工。
20
在实现这两个需求之前,先来回顾一下React 类组件的2个生命周期方法:
2
componentDidMount()
componentDidUpdate(prevProps)
props
state
组件 <EmployeesPage>使用上面两个生命周期方法实现获取逻辑:
<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。
fetch()
setState
employees
this.fetch()在componentDidMount()生命周期方法中执行:它在组件初始渲染时获取员工数据。
this.fetch()
当咱们关键字进行过滤时,将更新 props.query 。每当 props.query 更新,componentDidUpdate()就会重新执行this.fetch()。
props.query
componentDidUpdate()
虽然生命周期方法相对容易掌握,但是基于类的方法存在样板代码使重用性变得困难。
这种方法很容易理解:componentDidMount()在第一次渲染时获取数据,而componentDidUpdate()在props更新时重新获取数据。
样板代码
基于类的组件需要继承React.Component,在构造函数中执行 super(props) 等等。
React.Component
super(props)
this
使用 this 关键字很麻烦。
代码重复
componentDidMount()和componentDidUpdate()中的代码大部分是重复的。
很难重用
员工获取逻辑很难在另一个组件中重用。
Hooks 是基于类获取数据方式更好的选择。作为简单的函数,Hooks 不像类组件那样还要继承,并且也更容易重用。
简单回忆一下useEffect(callback[, deps]) Hook 。这个hook在挂载后执行callback ,并且当依赖项deps发生变化时重新渲染。
useEffect(callback[, deps])
callback
deps
如下示例所示,在<EmployeesPage>中使用useEffect()获取员工数据:
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 方法 。
useEffect(fetch, [query])
fetch
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} />; }
从useEmployeesFetch()提到所需要的值。组件<EmployeesPage>没有相应的获取逻辑,只负责渲染界面工作。
useEmployeesFetch()
更好的是,可以在需要获取雇员的任何其他组件中重用useEmployeesFetch()。
清楚和简单
Hooks没有样板代码,因为它们是普通的函数。
可重用性
在 Hooks 中实现的获取数据逻辑很容易重用。
Hooks 有点违反直觉,因此在使用之前必须理解它们,Hooks 依赖于闭包,所以一定要很好地了解它们。
使用Hooks,仍然必须使用命令式方法来执行数据获取。
Suspense 提供了一种声明性方法来异步获取React中的数据。
Suspense
注意:截至2019年11月,Suspense 处于试验阶段。
<Suspense>包装执行异步操作的组件:
<Suspense>
<Suspense fallback={<span>Fetch in progress...</span>}> <FetchSomething /> </Suspense>
数据获取时,Suspense将显示fallback中的内容,当获取完数据后,Suspense将使用获取到数据渲染<FetchSomething />。
fallback
<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>
<EmployeesFetch>中的resource.employees是一个特殊包装的promise,它在背后与Suspense进行通信。这样,Suspense就知道“挂起” <EmployeesFetch>的渲染要花多长时间,并且当资源准备就绪时,就开始执行渲染工作。
resource.employees
promise
最大的优点是:Suspense 以声明性和同步的方式处理异步操作。组件没有复杂数据获取逻辑,而是以声明方式使用资源来渲染内容。在组件内部没有生命周期,没有 Hooks,async/await,没有回调:仅展示界面。
async/await
声明式
Suspense 以声明的方式在React中执行异步操作。
简单
声明性代码使用起来很简单,这些组件没有复杂的数据获取逻辑。
松耦合与获取实现
使用Suspense的组件看不出如何获取数据:使用 REST 或 GraphQL。Suspense设置一个边界,保护获取细节泄露到组件中。
如果请求了多个获取操作,那么Suspense会使用最新的获取请求。
原文:https://dmitripavlutin.com/react-fetch-lifecycle-methods-hooks-suspense/
很长一段时间以来,生命周期方法一直是获取数据方式的唯一解决方案。然而,使用它们获取数据会有很多样板代码、重复和可重用性方面的问题。
使用 Hooks 获取数据是更好的选择:更少的样板代码。
Suspense的好处是声明性获取。咱们的组件不会被获取实现细节弄得乱七八糟。Suspense更接近于React本身的声明性本质。
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
https://github.com/qq449245884/xiaozhi
因为篇幅的限制,今天的分享只到这里。如果大家想了解更多的内容的话,可以去扫一扫每篇文章最下面的二维码,然后关注咱们的微信公众号,了解更多的资讯和有价值的内容。
每次整理文章,一般都到2点才睡觉,一周4次左右,挺苦的,还望支持,给点鼓励
The text was updated successfully, but these errors were encountered:
No branches or pull requests
阿里云最近在做活动,低至2折,真心觉得很划算了,可以点击本条内容或者链接进行参与:
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
为了保证的可读性,本文采用意译而非直译。
在执行 I/O 操作(例如数据提取)时,要先发送网络请求,然后等待响应,接着将响应数据保存到组件的状态,最后进行渲染。
在 React 中生命周期方法、Hooks和 Suspense是获取数据的方法。接下用事例演示一下如何使用它们并说明每种方法的优点和缺点,以便咱们更好的编写异步操作代码。
1.使用生命周期方法请求数据
应用程序
Employees.org
做两件事:1.一进入程序就获取
20
名员工。2.可以通过过滤条件来筛选员工。
在实现这两个需求之前,先来回顾一下React 类组件的
2
个生命周期方法:componentDidMount()
:组件挂载后执行componentDidUpdate(prevProps)
:当props
或state
改变时执行组件
<EmployeesPage>
使用上面两个生命周期方法实现获取逻辑:打开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()
中的代码大部分是重复的。很难重用
员工获取逻辑很难在另一个组件中重用。
2.使用 Hooks 获取数据
Hooks 是基于类获取数据方式更好的选择。作为简单的函数,Hooks 不像类组件那样还要继承,并且也更容易重用。
简单回忆一下
useEffect(callback[, deps])
Hook 。这个hook在挂载后执行callback
,并且当依赖项deps
发生变化时重新渲染。如下示例所示,在
<EmployeesPage>
中使用useEffect()
获取员工数据:打开codesandbox可以查看
useEffect()
如何获取数据。可以看到使用 Hooks 的
<EmployeesPage>
比使用类组件方式简单了很多。在
<EmployeesPage>
函数组件中的useEffect(fetch, [query])
,初始渲染之后执行fetch
回调。此外,当依赖项query
更新时也会重新执行fetch
方法。
但仍有优化的空间。Hooks 允许咱们从
<EmployeesPage>
组件中提取雇员获取逻辑,来看看:从
useEmployeesFetch()
提到所需要的值。组件<EmployeesPage>
没有相应的获取逻辑,只负责渲染界面工作。更好的是,可以在需要获取雇员的任何其他组件中重用
useEmployeesFetch()
。优点
清楚和简单
Hooks没有样板代码,因为它们是普通的函数。
可重用性
在 Hooks 中实现的获取数据逻辑很容易重用。
缺点
需要前置知识
Hooks 有点违反直觉,因此在使用之前必须理解它们,Hooks 依赖于闭包,所以一定要很好地了解它们。
必要性
使用Hooks,仍然必须使用命令式方法来执行数据获取。
3.使用 suspense 获取数据
Suspense
提供了一种声明性方法来异步获取React中的数据。注意:截至2019年11月,Suspense 处于试验阶段。
<Suspense>
包装执行异步操作的组件:数据获取时,
Suspense
将显示fallback
中的内容,当获取完数据后,Suspense
将使用获取到数据渲染<FetchSomething />
。来看看怎么使用
Suspense
:打开codesandbox可以查看
Suspense
如何获取数据。<EmployeesPage>
使用Suspense
处理组件将获取到数据传递给<EmployeesFetch>
组件。<EmployeesFetch>
中的resource.employees
是一个特殊包装的promise
,它在背后与Suspense
进行通信。这样,Suspense
就知道“挂起”<EmployeesFetch>
的渲染要花多长时间,并且当资源准备就绪时,就开始执行渲染工作。最大的优点是:
Suspense
以声明性和同步的方式处理异步操作。组件没有复杂数据获取逻辑,而是以声明方式使用资源来渲染内容。在组件内部没有生命周期,没有 Hooks,async/await
,没有回调:仅展示界面。优点
声明式
Suspense
以声明的方式在React中执行异步操作。简单
声明性代码使用起来很简单,这些组件没有复杂的数据获取逻辑。
松耦合与获取实现
使用
Suspense
的组件看不出如何获取数据:使用 REST 或 GraphQL。Suspense
设置一个边界,保护获取细节泄露到组件中。标准状态
如果请求了多个获取操作,那么
Suspense
会使用最新的获取请求。原文:https://dmitripavlutin.com/react-fetch-lifecycle-methods-hooks-suspense/
4.总结
很长一段时间以来,生命周期方法一直是获取数据方式的唯一解决方案。然而,使用它们获取数据会有很多样板代码、重复和可重用性方面的问题。
使用 Hooks 获取数据是更好的选择:更少的样板代码。
Suspense
的好处是声明性获取。咱们的组件不会被获取实现细节弄得乱七八糟。Suspense
更接近于React本身的声明性本质。代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dmitripavlutin.com/react-fetch-lifecycle-methods-hooks-suspense/
交流(欢迎加入群,群工作日都会发红包,互动讨论技术)
阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pxuujn3r
干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。
因为篇幅的限制,今天的分享只到这里。如果大家想了解更多的内容的话,可以去扫一扫每篇文章最下面的二维码,然后关注咱们的微信公众号,了解更多的资讯和有价值的内容。
每次整理文章,一般都到2点才睡觉,一周4次左右,挺苦的,还望支持,给点鼓励
The text was updated successfully, but these errors were encountered: