在React js中进行API调用的正确方法是什么?

JavaScript

阳光Itachi

2020-03-11

我最近从Angular转到了ReactJs。我正在使用jQuery进行API调用。我有一个API,可返回要打印在列表中的随机用户列表。

我不确定如何编写我的API调用。最佳做法是什么?

我尝试了以下操作,但未得到任何输出。如果需要,我愿意实现替代API库。

下面是我的代码:

import React from 'react';

export default class UserList extends React.Component {    
  constructor(props) {
    super(props);
    this.state = {
      person: []
    };
  }

  UserList(){
    return $.getJSON('https://randomuser.me/api/')
    .then(function(data) {
      return data.results;
    });
  }

  render() {
    this.UserList().then(function(res){
      this.state = {person: res};
    });
    return (
      <div id="layout-content" className="layout-content-wrapper">
        <div className="panel-list">
          {this.state.person.map((item, i) =>{
            return(
              <h1>{item.name.first}</h1>
              <span>{item.cell}, {item.email}</span>
            )
          })}
        <div>
      </div>
    )
  }
}

第825篇《在React js中进行API调用的正确方法是什么?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

9个回答
西门小宇宙 2020.03.11

1)您可以使用F etch API从End Point获取数据:

Github为用户获取所有安息的示例

  /* Fetch GitHub Repos */
  fetchData = () => {

       //show progress bar
      this.setState({ isLoading: true });

      //fetch repos
      fetch(`https://api.github.com/users/hiteshsahu/repos`)
      .then(response => response.json())
      .then(data => {
        if (Array.isArray(data)) {
          console.log(JSON.stringify(data));
          this.setState({ repos: data ,
                         isLoading: false});
        } else {
          this.setState({ repos: [],
                          isLoading: false  
                        });
        }
      });
  };

2)其他替代品是Axios

使用axios,您可以省去将http请求的结果传递给.json()方法的中间步骤。Axios只是返回您期望的数据对象。

  import axios from "axios";

 /* Fetch GitHub Repos */
  fetchDataWithAxios = () => {

     //show progress bar
      this.setState({ isLoading: true });

      // fetch repos with axios
      axios
          .get(`https://api.github.com/users/hiteshsahu/repos`)
          .then(result => {
            console.log(result);
            this.setState({
              repos: result.data,
              isLoading: false
            });
          })
          .catch(error =>
            this.setState({
              error,
              isLoading: false
            })
          );
}

现在,您可以选择使用以下任何一种策略来获取数据 componentDidMount

class App extends React.Component {
  state = {
    repos: [],
   isLoading: false
  };

  componentDidMount() {
    this.fetchData ();
  }

同时,您可以在加载数据时显示进度条

   {this.state.isLoading && <LinearProgress />}
斯丁 2020.03.11

作为外部API调用的最佳实践,是React Lifecycle方法componentDidMount(),在执行API调用之后,您应该更新本地状态以触发新的render()方法调用,然后更新后的本地状态中的更改将应用于组件视图。

作为React中初始外部数据源调用的另一种选择,是指向类的Constructor()方法。构造函数是在初始化组件对象实例时执行的第一个方法。您可以在高阶组件的文档示例中看到此方法

不应将方法componentWillMount()UNSAFE_componentWillMount()用于外部API调用,因为它们已被弃用。在这里您会看到常见原因,为什么不赞成使用此方法。

无论如何,您绝不能使用render()方法或直接从render()调用的方法作为外部API调用的点。如果这样做,您的应用程序将被阻止

小哥老丝 2020.03.11

您还可以在函数组件中使用钩子获取数据

带有api调用的完整示例:https : //codesandbox.io/s/jvvkoo8pq3

第二个示例:https : //jsfiddle.net/bradcypert/jhrt40yv/6/

const Repos = ({user}) => {
  const [repos, setRepos] = React.useState([]);

  React.useEffect(() => {
    const fetchData = async () => {
        const response = await axios.get(`https://api.github.com/users/${user}/repos`);
        setRepos(response.data);
    }

    fetchData();
  }, []);

  return (
  <div>
    {repos.map(repo =>
      <div key={repo.id}>{repo.name}</div>
    )}
  </div>
  );
}

ReactDOM.render(<Repos user="bradcypert" />, document.querySelector("#app"))
逆天AGreen 2020.03.11

仅在此处添加当前useEffect可能是现在放置api调用的地方。参见https://btholt.github.io/complete-intro-to-react-v5/effects

ItachiGreen 2020.03.11

一种干净的方法是使用try / catch函数componentDidMount内部进行异步API调用

调用API时,我们会收到响应。然后,我们对其应用JSON方法,以将响应转换为JavaScript对象。然后,我们从该响应对象中仅获取其子对象“ results”(data.results)。

首先,我们将状态为“ userList”的数组定义为一个空数组。一旦我们进行API调用并从该API接收数据,我们就会使用setState方法将“结果”分配给userList

在render函数内部,我们告诉userList将来自状态。由于userList是对象数组,我们通过它映射,以显示每个对象“用户”的图片,名称和电话号码。要检索此信息,我们使用点符号(例如user.phone)。

注意:根据您的API,您的响应可能看起来有所不同。Console.log整个“响应”,以查看您需要从中获取哪些变量,然后在setState中分配它们。

UserList.js

import React, { Component } from "react";

export default class UserList extends Component {
   state = {
      userList: [], // list is empty in the beginning
      error: false
   };

   componentDidMount() {
       this.getUserList(); // function call
   }

   getUserList = async () => {
       try { //try to get data
           const response = await fetch("https://randomuser.me/api/");
           if (response.ok) { // ckeck if status code is 200
               const data = await response.json();
               this.setState({ userList: data.results});
           } else { this.setState({ error: true }) }
       } catch (e) { //code will jump here if there is a network problem
   this.setState({ error: true });
  }
};

  render() {
  const { userList, error } = this.state
      return (
          <div>
            {userList.length > 0 && userList.map(user => (
              <div key={user}>
                  <img src={user.picture.medium} alt="user"/>
                  <div>
                      <div>{user.name.first}{user.name.last}</div>
                      <div>{user.phone}</div>
                      <div>{user.email}</div>
                  </div>
              </div>
            ))}
            {error && <div>Sorry, can not display the data</div>}
          </div>
      )
}}
米亚伽罗L 2020.03.11

我希望您看看redux http://redux.js.org/index.html

它们具有处理异步调用(即API调用)的定义非常明确的方式,并且我建议使用fetch请求 npm包,而不是使用jQuery进行API调用,现代浏览器目前支持fetch,但也可以使用shim服务器端。

还有另一个令人惊奇的软件包superagent,在发出API请求时它有很多选择,而且非常易于使用。

LEYJim 2020.03.11

React v16文档中的这一部分将回答您的问题,请继续阅读有关componentDidMount()的内容:

componentDidMount()

挂载组件后立即调用componentDidMount()。需要DOM节点的初始化应在此处进行。如果需要从远程端点加载数据,这是实例化网络请求的好地方。此方法是设置任何订阅的好地方。如果这样做,请不要忘记取消订阅componentWillUnmount()。

如您所见,componentDidMount被认为是进行api调用,访问节点的最佳位置和周期,这意味着此时可以安全地进行调用,更新视图或在文档准备就绪时执行任何操作(如果您愿意)使用jQuery,它应该以某种方式提醒您document.ready()函数,在这里您可以确保一切准备就绪,可以在代码中进行任何操作...

凯Gil 2020.03.11

渲染函数应该是纯函数,这意味着它仅使用状态和道具进行渲染,从不尝试在渲染中修改状态,这通常会导致难看的错误并显着降低性能。如果您分开数据获取并在React App中提出问题,这也是一个好点。我建议您阅读这篇文章,它很好地解释了这个想法。https://medium.com/@learnreact/container-components-c0e67432e005#.sfydn87nm

阳光村村 2020.03.11

您可能需要查看Flux体系结构我也建议您检查React-Redux的实现将您的api调用放入您的操作中。这比将它们全部放入组件中要干净得多。

操作是一种帮助程序方法,您可以调用这些方法来更改应用程序状态或进行api调用。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android