在 react js 中调用 API 的正确方法是什么?

IT技术 javascript jquery reactjs
2021-02-11 12:41:23

我最近从 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>
    )
  }
}
6个回答

在这种情况下,你可以在里面做ajax调用componentDidMount,然后更新state

export default class UserList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {person: []};
  }

  componentDidMount() {
    this.UserList();
  }

  UserList() {
    $.getJSON('https://randomuser.me/api/')
      .then(({ results }) => this.setState({ person: results }));
  }

  render() {
    const persons = this.state.person.map((item, i) => (
      <div>
        <h1>{ item.name.first }</h1>
        <span>{ item.cell }, { item.email }</span>
      </div>
    ));

    return (
      <div id="layout-content" className="layout-content-wrapper">
        <div className="panel-list">{ persons }</div>
      </div>
    );
  }
}
@Raj Rj 这些天我认为它是 Redux
2021-03-13 12:41:23
它奏效了,谢谢.. 你能否建议我“哪个是更好的状态管理的最佳库”
2021-03-22 12:41:23
Redux 最近比较流行,它的风格来自于函数式编程。如果你来自 OOP 风格,Mobx ( mobxjs.github.io/mobx ) 是一个优秀的状态管理库,它让你专注于编写业务代码并最终减少你的样板代码
2021-03-29 12:41:23

您可能想查看Flux Architecture我还建议查看React-Redux 实现将您的 api 调用放在您的操作中。它比将所有内容都放在组件中要干净得多。

Actions 是一种辅助方法,您可以调用它们来更改应用程序状态或执行 api 调用。

Troper 谢谢你。那么,我应该将 API 相关调用保存在单独的文件中吗?我如何在我的“组件类”中调用它们?我应该遵循什么文件夹结构?最佳实践是什么?PS-我是新手,所以问这个基本问题。
2021-03-19 12:41:23
在 redux 实现中,action 方法被注入到组件中。这些方法现在将成为您可以调用的组件的道具。您可以查看react-redux-starter-kit的结构。
2021-04-11 12:41:23

使用fetch里面的方法componentDidMount来更新状态:

componentDidMount(){
  fetch('https://randomuser.me/api/')
      .then(({ results }) => this.setState({ person: results }));
}

这个讨论已经有一段时间了,@Alexander T. 的回答为像我这样的 React 新手提供了一个很好的指导。我将分享一些关于多次调用相同 API 以刷新组件的额外知识,我认为这可能是初学者的常见问题。

componentWillReceiveProps(nextProps),来自官方文档

如果您需要更新状态以响应 prop 更改(例如,重置它),您可以比较 this.props 和 nextProps 并在此方法中使用 this.setState() 执行状态转换。

我们可以得出结论,这里是我们处理来自父组件的 props、调用 API 和更新状态的地方。

基于@Alexander T. 的例子:

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

  componentDidMount() {
   //For our first load. 
   this.UserList(this.props.group); //maybe something like "groupOne"
  }

  componentWillReceiveProps(nextProps) {
    // Assuming parameter comes from url.
    // let group = window.location.toString().split("/")[*indexParameterLocated*];
    // this.UserList(group);
   
    // Assuming parameter comes from props that from parent component.
    let group = nextProps.group; // Maybe something like "groupTwo" 
    this.UserList(group);
  }

  UserList(group) {
    $.getJSON('https://randomuser.me/api/' + group)
      .then(({ results }) => this.setState({ person: results }));
  }

  render() {
    return (...)
  }
}

更新

componentWillReceiveProps() 将被弃用。

这里只是生命周期中的一些方法(都在Doc 中)我认为它们与在一般情况下部署 API 相关: 在此处输入图片说明

参考上图:

  • 将 API 部署在 componentDidMount()

    此处调用 API 的正确场景是该组件的内容(来自 API 的响应)将是静态的,componentDidMount()仅在组件挂载时触发一次,即使是从父组件传递的新 props 或有操作可引导re-rendering
    该组件会检查差异以重新渲染但不重新安装
    引用自doc

如果您需要从远程端点加载数据,这是实例化网络请求的好地方。


  • 将 API 部署在 static getDerivedStateFromProps(nextProps, prevState)

我们应该注意到,有两种组件更新setState() 在当前组件不会触发此方法,但重新渲染或新props将父组件我们可以发现这个方法在挂载时也会触发。

如果我们想使用当前组件作为模板,这是一个合适的部署 API 的地方,并且进行 API 调用的新参数是来自父组件的 props
我们从 API 收到不同的响应,并state在此处返回一个新的响应来更改此组件的内容。

例如:
我们在父组件中有一个不同汽车的下拉列表,该组件需要显示所选汽车的详细信息。


  • 将 API 部署在 componentDidUpdate(prevProps, prevState)

与 不同static getDerivedStateFromProps(),除了初始渲染之外,每次渲染后都会立即调用此方法。我们可以在一个组件中调用 API 并呈现差异。

扩展前面的例子:
显示Car的详细信息的组件可能包含这个汽车的系列列表,如果我们想查看2013年生产的一个,我们可以点击或选择或...列表项引导一个第一个setState()反映这一点此组件中的行为(例如突出显示列表项),接下来componentDidUpdate()我们发送带有新参数(状态)的请求。得到响应后,我们setState()再次对Car details的不同内容进行渲染。为防止后面componentDidUpdate()造成无限循环,我们需要通过prevState这个方法开始时的状态比较来决定是否发送API并渲染新的内容。

这种方法确实可以像static getDerivedStateFromProps()props一样使用,但需要props通过使用prevProps. 并且我们需要配合componentDidMount()来处理最初的 API 调用。

引用自doc

... 这也是一个做网络请求的好地方,只要你比较当前的 props 和之前的 props ...

我想让你看看 redux http://redux.js.org/index.html

他们有很好定义的方式来处理异步调用,即 API 调用,而不是使用 jQuery 进行 API 调用,我想推荐使用fetchrequest npm 包,现代浏览器目前支持fetch,但也可以使用 shim服务器端。

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