React中获取数据的3种方式及其优缺点已经收录在网站中,并且对之前好评较多的文章进行了分类,同时也整理了很多我的文档和教程资料。欢迎来到星和完美。面试时可参考考点复习。我希望我们能在一起。为了保证更好的可读性,本文采用意译而非直译。当执行I/O操作(例如数据获取)时,您发送网络请求,等待响应,将响应数据保存到组件的状态,最后呈现。生命周期方法、Hooks和Suspense是React中获取数据的方式。接下来通过实例来演示如何使用,并说明每种方法的优缺点,以便我们更好的编写异步操作代码。1.使用生命周期方法请求数据应用程序Employees.org做了两件事:1.一进入程序就获取20名员工。2.可按筛选条件筛选员工。在实现这两个需求之前,先回顾一下React类组件的两个生命周期方法:componentDidMount():组件挂载后执行componentDidUpdate(prevProps):当props或state改变时执行组件使用以上两个生命周期cycle方法实现了获取逻辑:this.state={employees:[],isFetching:true};}componentDidMount(){this.fetch();}componentDidUpdate(prevProps){if(prevProps.query!==this.props.query){this.fetch();}}asyncfetch(){this.setState({isFetching:true});constemployees=awaitfetchEmployees(this.props.query);this.setState({employees,isFetching:false});}render(){const{isFetching,employees}=this.state;if(isFetching){return获取员工数据...
;}return;}}打开codesandbox查看获取流程。有一个异步方法fetch()来获取数据。获取请求完成后,使用setState方法更新员工。this.fetch()在componentDidMount()生命周期方法中执行:它在组件最初呈现时获取员工数据。当我们按关键字过滤时,props.query将被更新。componentDidUpdate()将在props.query更新时重新执行this.fetch()。虽然生命周期方法相对容易掌握,但基于类的方法具有样板代码,这使得重用性变得困难。优点这种方法很容易理解:componentDidMount()在第一次渲染时获取数据,而componentDidUpdate()在props更新时重新获取数据。缺点Boilerplate代码基于类的组件需要继承React.Component,在构造函数中实现super(props)等,使用this关键字比较麻烦。代码重复componentDidMount()和componentDidUpdate()中的代码大部分是重复的。难以重用Employee获取逻辑很难在另一个组件中重用。2、使用Hooks获取数据Hooks是基于类获取数据的更好选择。作为简单的功能,Hooks不像类组件那样需要继承,也更容易复用。回想一下useEffect(callback[,deps])Hook。该挂钩在挂载后执行回调,并在依赖deps更改时重新呈现。如下例所示,使用中的useEffect()获取员工数据:const[isFetching,setFetching]=useState(false);const[员工,setEmployees]=useState([]);useEffect(functionfetch(){(asyncfunction(){setFetching(true);setEmployees(awaitfetchEmployees(query));setFetching(false);})();},[query]);if(isFetching){return正在获取员工....
;}return;}打开codesandbox看看useEffect()是如何获取数据的。可以看到使用Hooks比使用类组件要简单得多。功能组件中的useEffect(fetch,[query]),在初始渲染后执行fetch回调。此外,更新依赖项查询时会重新执行fetch方法。但仍有优化空间。Hooks允许我们从组件中提取员工获取逻辑,让我们看一下:importReact,{useState}from'react';从“./EmployeesList”导入员工列表;import{fetchEmployees}from"./fake-fetch";functionuseEmployeesFetch(query){//这一行改变了const[isFetching,setFetching]=useState(false);const[员工,setEmployees]=useState([]);useEffect(functionfetch{(asyncfunction(){setFetching(true);setEmployees(awaitfetchEmployees(query));setFetching(false);})();},[query]);返回[isFetching,employees];}functionEmployeesPage({query}){const[employees,isFetching]=useEmployeesFetch(query);//这一行改变了if(isFetching){returnFetchingemployees....
;}return;}来自useEmployeesFetch()提及期望的值。组件没有对应的获取逻辑,只负责界面的渲染。更好的是,useEmployeesFetch()可以在任何其他需要获取员工的组件中重复使用。优点清晰和简单Hooks没有样板代码,因为它们是普通函数。可重用性Hooks中实现的抓取逻辑很容易重用。缺点需要先验知识Hooks有点违反直觉,所以在使用之前一定要先了解一下,Hooks依赖于闭包,所以一定要了解清楚。必要性使用Hooks,仍然需要使用命令式的方式来执行数据获取。3、使用suspense获取数据Suspense提供了一种声明式的方式在React中异步获取数据。注意:截至2019年11月,Suspense处于试验阶段。包装了执行异步操作的组件:Fetchinprogress...}>当数据被抓取时,Suspense会把内容显示在fallback,当获取到数据时,Suspense会使用获取到的数据来渲染。让我们看看如何使用Suspense:importReact,{Suspense}from"react";importEmployeesListfrom"./EmployeesList";functionEmployeesPage({resource}){return(Fetchingemployees....}>);}functionEmployeesFetch({resource}){constemployees=resource.employees.read();return;}打开codesandbox看看Suspense是如何获取数据的。使用Suspense处理组件将获取的数据传递给组件。中的resource.employees是一个特殊包装的承诺,它在幕后与Suspense通信。这样,Suspense就知道要“暂停”渲染多长时间,当资源准备好时,渲染工作就开始了。最大的优势:Suspense以声明和同步的方式处理异步操作。组件没有复杂的数据获取逻辑,而是以声明方式使用资源来呈现内容。在组件内部没有生命周期、没有Hooks、异步/等待、没有回调:只有接口。优点DeclarativeSuspense以声明的方式在React中执行异步操作。简单的声明式代码易于使用,这些组件没有复杂的数据获取逻辑。与Fetch实现的松散耦合使用Suspense的组件看不到如何获取数据:使用REST或GraphQL。Suspense设置了一个边界,以防止访问细节泄露到组件中。标准状态如果请求多个fetch操作,Suspense将使用最新的fetch请求。原文:https://dmitripavlutin.com/re...4.总结长期以来,生命周期方法一直是解决如何获取数据的唯一方案。然而,使用它们来获取数据会带来大量样板代码、重复和可重用性问题。使用Hooks获取数据是一个更好的选择:更少的样板代码。Suspense的好处是声明式抓取。我们的组件不会因获取实现细节而变得混乱。Suspense更接近于React本身的声明性。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://dmitripavlutin.com/re...交流文章每周持续更新。可以微信搜索“大千世界”阅读即时更新(比博文早一两篇)。这篇文章在GitHubhttps://github.com/qq449245884/xiaozhi已经收录,整理了很多我的文档。欢迎star和改进。可以参考考点面试。另外,关注公众号,后台会回复福利,看到福利就知道了。