前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在 React 应用中获取数据

在 React 应用中获取数据

作者头像
前端达人
发布2018-10-18 14:51:42
8.4K0
发布2018-10-18 14:51:42
举报
文章被收录于专栏:前端达人前端达人

可以说 React 是构建 web 应用最流行的库。然而,它并不是全能的 web 框架。它只关注 MVC 中的 view 模块。

React 整个生态系统可以解决其它问题。这篇教程中,你将会学到如何在 React web 应用中获取数据并显示。这很重要。 在整个 React 组件中有几个地方都可以获取远程数据。何时获取数据是另外一个问题。你还需要考虑用何种技术获取数据、数据存储在哪里。

在教程结束后,你会清楚的知道 React 中该如何获取数据,不同方法的利弊和如何在 React 应用中使用这些技术。

开始

让我们用 create-react-app 创建一个 React 应用的框架:

> create-react-app react-data-fetcher

我们会得到一个精致的结构目录。如果,你不熟悉 create-react-app,可以先看看 README 文件。

创建简单的服务

我创建了一个简单的 quotes 服务。这篇教程的重点不是它,它可以提供远程 API 用来演示如何在 React 中获取数据。 为了满足你们的好奇心,它是一个基于 hug 框架 (http://www.hug.rest/)Python 3 的应用,用 Redis 做持久化存储。

API 非常简单。/quotes 是一个简单接口。通过一个 GET 请求返回所有的 quotes,并且你可以通过 POST 请求新增一条记录。

完整的代码可以在 GitHub (https://github.com/the-gigi/quote-service)查看。

App 预览

这个 React 应用 Demo 可以和 quote 服务通信、显示所有的 quote 并可以添加新的记录。

这是截图:

App 的结构非常简单。我用 create-react-app 创建了一个基础框架并在 src 目录中添加两个组件:QuoteList 和 AddQuoteForm。以下是详细的目录结构(不包含 node_moudules):

显示 Quotes

QuoteList 函数组件以无序列表的形式展示所有的 quotes。它需要传入一组数据字符串:

代码语言:javascript
复制
import React from 'react'
const QuoteList = ({quotes}) =>
    quotes.map(quote => <li key={quote}>{quote}</li>)
export default QuoteList

通过 Fetch 获取远程数据

Fetch 是基于 promise 的 API,它会返回一个对象。为了得到实际的 JSON 数据,你需要对响应对象执行 json() 方法。

代码语言:javascript
复制
fetchQuotes = () => {
    this.setState({...this.state, isFetching: true})
    fetch(QUOTE_SERVICE_URL)
        .then(response => response.json())
        .then(result => this.setState({quotes: result,
            isFetching: false}))
        .catch(e => console.log(e));}
}

何时何地执行获取数据的代码

当然 React 都是组件。重点是何时何地才去加载获取远程数据呢! 如果你能很好的组织代码,你应该会有很多的通用组件和一些特定的组件。React 和 JavaScript 通常非常灵活,你可以在任何地方注入业务逻辑。

因为我希望数据一直是最新的,所以,会以轮询的方式通过 REST API 获取远程数据。 但是,初始化数据也非常重要。React 组件的生命周期方法允许你在特定的时间执行你需要的业务逻辑。 componentDidMount()方法会在组件可访问的时候执行,此时就可以改变组件的 state。这时候获取远程数据是非常合适的。

看起来就像这样:

代码语言:javascript
复制
componentDidMount() {
    this.fetchQuotes()
}

如果,你想缩短页面的第一次可见的时间,你可以考虑在 componentWillMount() 方法中初始化异步数据,但是,这有可能会在组件未装载前完成数据请求。我不推荐这么操作。

数据更新频率

在 componentDidMount() 方法中初始化数据是很合理的,但是,我需要经常更新数据。基于 REST API,只有通过轮询的方式解决。Quote 服务器非常简单,而且始终都会返回所有的 quotes。

大多数可扩展服务都会提供方法检查 HTTP 中的 if-modify-since 和 eTag 判断数据是否有更新。我们的应用中只是在 componentDidMount() 方法中启动一个 5s 的定时器更新数据,然后,在 componentWillUnmount() 方法清除定时器

代码语言:javascript
复制
componentDidMount() {
    this.fetchQuotes()
    this.timer = setInterval(() => this.fetchQuotes(), 5000);
}
componentWillUnmount() {
    this.timer = null;
} 

轮询的时间间隔由应用决定。如果,你需要实时更新,并后台有性能要求,可以考虑用 WebSockets 代替 REST。

加载数据延迟的处理

有时候加载数据会花费很长时间。在这种下,显示一个进度条或者一个醒目的动画让用户知道程序正在处理,这对用户体验有很大的帮助。 当用户在初始化数据的时候(比如:点击搜索按钮)这很重要。

在演示 app 中,当请求时数据时我简单的显示一条提示信息:“请求数据中...”。在 App 组件的 render() 方法中,通过检查state.isFetching 的值来决定是否显示提示信息。

代码语言:javascript
复制
render() {
    const title = 'Quotes for ya!'
    let now = new Date()
    return (
        <div className='App'>
            <h2 className='App-title'>{title}</h2>
            <p>{this.state.isFetching ? 'Fetching quotes...' : ''}</p>
            <QuoteList quotes={this.state.quotes} />
            <AddQuoteForm quote_service_url={QUOTE_SERVICE_URL}/>
        </div>
    );
}

fetchQuotes() 方法在初始化开始的时候会把 state.isFetching 的值更新为 true,当有响应返回的时候就切换回 false:

fetchQuotes = () => {

代码语言:javascript
复制
    this.setState({...this.state, isFetching: true})
    fetch(QUOTE_SERVICE_URL)
        .then(response => response.json())
        .then(result => this.setState({quotes: result,
            isFetching: false}))
        .catch(e => console.log(e));
}

错误的处理

在这里我对错误的处理非常有限只是捕获错误并输出到控制台。在你的应用中,你可以执行一些重试逻辑、提示用户或者显示一些预设的内容。

Fetch API vs. Axios

Fetch API 是有缺陷的。处理响应的时候必须额外的经过 JSON 处理。它也不会捕获所有的错误。 例如,404 将会做为一个正常的响应返回。你必须主动检查响应的状态码并处理捕获的网络异常。

因此你必须在两个地方处理错误。但是,你可以使用 axios.js 解决这些问题,在添加额外代价的情况下使用更简洁的代码。使用 axios 的代码看起来就像这样:

代码语言:javascript
复制
fetchQuotes = () => {
    this.setState({...this.state, isFetching: true})
    axios.get(QUOTE_SERVICE_URL)
        .then(response => this.setState({quotes: response.data,

            isFetching: false}))
        .catch(e => console.log(e);

}

这看起来差别并不大,但是这非常有帮助。使用 axios 添加新的记录代码也非常简洁。以下是 fetch 的版本:

代码语言:javascript
复制
handleSubmitWithFetch = event => {
    let data = new FormData()
    data.append('quote', this.state.quote)
    fetch(this.props.quote_service_url,
        {method: 'POST', body: data})
        .then(response => response.json())
        .catch(e => console.log(e));
    event.preventDefault();

}

这是 axios 的版本:

代码语言:javascript
复制
handleSubmit = event => {
    axios.post(this.props.quote_service_url,
        {'quote': this.state.quote})
        .then(r => console.log(r))
        .catch(e => console.log(e));    
     event.preventDefault();
}

在这篇教程中,你学到了如何在 React 组件中异步加载数据。我们也提到了相关的生命周期方法、轮询、进度条和错误的处理。

我们也了解到两个基于 promise 的库:fetch API 和 axios.js。现在,你可以构建自己的 React 应用了。

在最近几年中,React 越来越流行。事实上,市场有很多可以供购买、审查、部署的项目。 如果,你查找更多的 React 资源,不要迟疑请看这里

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档