详解如何使用React Hooks请求数据并渲染
前言
在日常的开发中,从服务器端异步获取数据并渲染是相当高频的操作。在以往使用React Class组件的时候,这种操作我们已经很熟悉了,即在Class组件的ponentDidMount中通过ajax来获取数据并setState,触发组件更新。
随着Hook的到来,我们可以在一些场景中使用Hook的写法来替代Class的写法。Hook中没有setState、ponentDidMount等函数,又如何做到从服务器端异步获取数据并渲染呢?本文将会介绍如何使用React的新特性Hook来编写组件并获取数据渲染。
数据渲染
先来看一个数据渲染的简单demo
import React, { useState } from 'react'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); return ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> ); } export default App;
在demo中,通过useState创建了一个叫data的内部state,该state中有一个产品列表数据保存产品数据。App组件通过data中的products来渲染产品列表数据到页面中。
但现在是写死的一个数据,如果我们期望从服务器端获取数据并渲染,那么就需要在组件渲染完成时fetch服务端数据,然后通过setData去改变state触发渲染。我们接下来准备用axios来获取数据。
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); useEffect(async () => { const result = await axios( 'https://c./api/products?date=today', ); setData(result.data); }); return ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> ); } export default App;
代码中使用到的useEffect就是hook的其中一种,叫effect hook。useEffect会在每次组件渲染的时候触发,我们使用它来获取数据并更新state。上面的代码是有缺陷的,你发现了吗?
没错,只要你运行一下,你就会发现程序进入了一个死循环。因为useEffect不仅在组件didMounts的时候被触发了,还在didUpdate的时候被触发了。在useEffect中获取数据后,通过setDate改变state,触发组件渲染更新,从而又进入到了useEffect中,无限循环下去。这并不是我们想要的结果。我们最初想要的,只是希望在didMounts的时候获取一次数据而已。所以,这种情况下,我们必须要给useEffect方法的第二个参数传入一个空[],以使得useEffect中的逻辑只在组件didMounts的时候被执行。
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); useEffect(async () => { const result = await axios( 'https://c./api/products?date=today', ); setData(result.data); },[]); //重点 return ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> ); } export default App;
虽然看起来这个错误比较低级,但确实比较多人在新上手hook时常常犯的问题。
,useEffect第二个参数,也可以传入值。当如果有值的时候,那useEffect会在这些值更新的时候触发。如果只是个空数组,则只会在didMounts的时候触发。
,执行这段代码,你会看到控制台警告,Promises and useEffect(async () => ...) are not supported, but you can call an async function inside an effect.。所以如果要使用async,需要修改下写法。
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); useEffect(() => { const fetchData = async()=>{ const result = await axios( 'https://c./api/products?date=today', ); setData(result.data); } fetchData(); },[]); return ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> ); } export default App;
体验优化
一般的应用在某些请求过程的交互设计上,会加上loading来缓解用户焦虑。那在Hook的写法中,如何实现呢?狼蚁网站SEO优化将会介绍。
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); const [isLoading, setIsLoading] = useState(false); useEffect(() => { const fetchData = async()=>{ setIsLoading(true); const result = await axios( 'https://c./api/products?date=today', ); setData(result.data); setIsLoading(false); } fetchData(); },[]); return ( {isLoading ? ( <div>Loading ...</div> ) : ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> )}; } export default App;
这里通过加入一个叫isLoading的state来实现。我们在fetch的开始和结束去改变isLoading的值,来控制return返回的组件内容,从而在请求前显示Loading组件,在请求后显示产品列表。
错误处理
请求的过程经常会由于各种原因失败,比如网络、服务器错误等等。所以错误处理必不可少的。
import React, { useState, useEffect } from 'react'; import axios from 'axios'; function App() { const [data, setData] = useState({ products: [{ productId: '123', productName: 'macbook' }] }); const [isLoading, setIsLoading] = useState(false); const [isError, setIsError] = useState(false); useEffect(() => { const fetchData = async()=>{ setIsError(false); setIsLoading(true); try{ const result = await axios( 'https://c./api/products?date=today', ); setData(result.data); }catch(e){ setIsError(true); } setIsLoading(false); } fetchData(); },[]); return ( <div> {isError && <div>出错了...</div>} {isLoading ? ( <div>Loading ...</div> ) : ( <ul> {data.products.map(i => ( <li key={i.productId}> {i.productName} </li> ))} </ul> )}; </div> } export default App;
当请求出错时,isError会被设置为true,触发渲染时,错误提示组件就会被渲染出来。这里的处理比较简单,在真实场景中,你可以在错误处理时加入更复杂的逻辑。isError会在每次hook运行的时候被重置。
读到这你已经基本学会了如何使用React Hooks获取数据并渲染组件了。
到此这篇关于如何使用React Hooks请求数据并渲染的文章就介绍到这了,更多相关React Hooks请求数据并渲染内容请搜索狼蚁SEO以前的文章或继续浏览狼蚁网站SEO优化的相关文章希望大家以后多多支持狼蚁SEO!
编程语言
- 甘肃哪有关键词排名优化购买方式有哪些
- 甘肃SEO如何做网站优化
- 河南seo关键词优化怎么做电话营销
- 北京SEO优化如何做QQ群营销
- 来宾百度关键词排名:提升您网站曝光率的关键
- 卢龙关键词优化:提升您网站排名的策略与技巧
- 山东网站优化的注意事项有哪些
- 四川整站优化怎样提升在搜索引擎中的排名
- 疏附整站优化:提升网站性能与用户体验的全新
- 海南seo主要做什么工作售后服务要做到哪些
- 荣昌百度网站优化:提升您网站的搜索引擎排名
- 河北seo网站排名关键词优化如何做SEO
- 江西优化关键词排名推广售后保障一般有哪些
- 古浪SEO优化:提升你的网站可见性
- 西藏网站排名优化怎么把网站排名在百度首页
- 如何提升阳东百度快照排名:详尽指南