在 React 中加载和使用外部数据

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

嗨,JavaScript 开发者们!我最近一直在学习 React。它非常有趣。感觉是用 JavaScript 编写代码的好方法。在我看来,它与早期的 jQuery 几乎有着相同的感觉。

不过,我得承认:我不是 React 大师。我即将向您展示如何在 React 中完成某些操作,而无需成为 CertifiedSuperReactPro®。虽然它有效,所以某些方面是正确的。

如今,您可能会在 React 中使用函数组件,并使用 hook 来获取数据,这就像处理组件“副作用”的现代方式,是对生命周期方法的现代改进。所以从这个意义上说,这篇文章已经过时了。但从概念上讲,它仍然是有意义的。我会在可以的地方用更多现代的东西更新它的小部分内容。

状态,状态,状态

在使用 React 的过程中,您学习的第一件事之一就是状态。它对 React 来说非常基础。它本质上是数据,可以是任何东西!

想象一下网站的评论部分。一些“状态”可能是

  • 评论表单是可见还是隐藏?
  • “提交评论”按钮是禁用还是启用?
  • 文本区域的当前值,以便可以在评论预览区域中使用它

但状态也是

  • 所有现有的评论!

我认为这是有道理的。评论是不同文章的一部分——在每个页面上都不同。它们是该页面数据的一部分。它们是状态。

// Just the state part of creating a React component
var Comments = React.createClass({

  getInitialState: function() {
    return {
      commentForm: {
        visible: true,
        submitVisible: false
      }
      comments: {
        unique-id-1: {
          name: "Chris Coyier",
          comment: "Lorem ipsum..."
        },
        unique-id-2: {
          name: "Sammy Sanddollar",
          comment: "Lorem ipsum..."
        }
      }
    }
  }

});

构建一个模拟的“评论表单”正是我用来帮助学习 React 的练习之一。我有一个 我和 Sarah Drasner 配对完成此练习的视频,您可以观看。

获取这些数据

在评论的情况下,您可能在自己的应用程序中拥有这些数据。

但数据不必来自您自己,数据可以来自任何地方。外部数据,如果您愿意的话。例如,来自 API。

Ajax

由于我们在这里完全在前端工作,因此从 API 获取数据属于 Ajax 的领域。我不知道您是怎么想的,但我认为 Ajax 就像这样

// jQuery!
$.ajax {
  url: "https://api.com/whatever"
}.then(function(data) {

});

但正如我最近 在一篇文章中了解到的那样,jQuery 并不是 React 的最佳朋友。jQuery 主要是一个 DOM 操作库,而 React 有自己的方法来做这些事情。jQuery 提供的 Ajax 功能很方便,但可以通过其他更专注的库来复制。

Axios 就是这样一个具有相同 API 的库。

示例数据

让我们使用一些简单、公开可用的 JSON

https://codepen.io/jobs.json

它只是一段描述 CodePen 招聘板上的所有职位发布的数据。

请求数据

在 Axios 中,请求数据就像这样

axios
  .get("https://codepen.io/jobs.json")
  .then(function(result) {    
    // we got it!
  });

使用 React Hook,我们会这样写…

import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {
  const [data, setData] = useState({ jobs: [] });
  useEffect(async () => {
    const result = await axios(
      'https://codepen.io/jobs.json',
    );
    setData(result.data);
  });
  return (
     <p>Loop over jobs data here and show results.</p>
  );
}
export default App;

使用外部数据设置状态

现在我们有了数据,让我们通过在 React 中设置状态使其可用于我们的应用程序。result 是 JSON 数据块。其主要部分是一个 job 数组,这正是我们的数据设置所期望的。我们使用 setState

var App = React.createClass({

  getInitialState: function() {
    return {
      jobs: []
    }
  },

  componentDidMount: function() {
    var _this = this;
    this.serverRequest = 
      axios
        .get("http://codepen.io/jobs.json")
        .then(function(result) {    
          _this.setState({
            jobs: result.data.jobs
          });
        })
  },

  componentWillUnmount: function() {
    this.serverRequest.abort();
  },

  render: function() {
    return (
      <div>
        {/* Render stuff here */}
      </div>
    )
  }
});

这里有一点错误处理。如果在 React(或您)决定移除组件时 Ajax 请求仍在进行,则 Ajax 请求将被中止。

此外,请确保渲染组件!

React.render(<App />, document.querySelector("#root"));

模板化数据

您不需要任何额外的库在 React 中进行模板化。HTML 模板化是 React 中一个非常基础的部分,尤其是在您使用 JSX(那些看起来像 JavaScript 中的 HTML 的东西)编写时,这非常推荐。

如果我们完全自己编写 HTML 来表示一个工作,它会是这样的

<div class="job">
  <a href="http://link-to-job.com">
    Company
    is looking for a 
    Full Time
    Web Designer
  </a>
</div>

我喜欢这样思考:考虑您想要的 HTML,然后将该 HTML 移动到 JSX 并用状态替换动态部分。

它变成了

var App = React.createClass({

  getInitialState: function() {
    // ...
  },

  componentDidMount: function() {
    // ...
  },

  componentWillUnmount: function() {
    // ...
  },

  render: function() {
    return (
      <div>
        <h1>Jobs!</h1>
        {this.state.jobs.map(function(job) {
          return (
            <div key={job.id} className="job">
              
                {job.company_name}
                is looking for a 
                {job.term}
                {job.title}
              
            </div>
          );
        })}
      </div>
    )
  }
});

演示

将所有这些放在一起,我们就得到了一个不错的 React 组件,它使用外部数据进行自身渲染!

查看 CodePen 上的示例
在 React 中加载外部数据
,由 Chris Coyier (@chriscoyier) 创建。
CodePen 上。


这与我脑海中所有与 React 相关的内容相吻合,例如我们的 最近的系列文章最近的视频以及最近关于 无头 CMS 的讨论。