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

Raj*_* Rj 117 javascript jquery reactjs

我最近从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>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

Ale*_* T. 85

在这种情况下,您可以在内部执行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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • Redux在这一天更受欢迎,其风格来自功能性编程.如果您来自OOP风格,Mobx(http://mobxjs.github.io/mobx/)是一个出色的状态管理库,它可以让您专注于编写业务代码并最终减少您的样板代码 (7认同)
  • 它工作,谢谢..你能不能建议我"哪一个是更好的国家管理的最佳图书馆" (2认同)
  • @Raj Rj这几天我觉得它是Redux (2认同)

Jei*_*per 23

您可以查看Flux Architecture.我还建议查看React-Redux实现.把api电话放在你的行动中.它比把它全部放在组件中更清洁.

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


小智 13

使用fetch内部方法componentDidMount更新状态.如下

....

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

....


Dev*_*hah 10

我希望你看一下redux http://redux.js.org/index.html

他们有非常明确的处理异步调用的方式,即API调用,而不是使用jQuery进行API调用,我建议使用fetchrequest npm包,现在浏览器支持fetch,但是也可以使用shim服务器端.

还有另一个惊人的包superagent,它在制作API请求时有很多选项,而且非常容易使用.


iam*_*sam 10

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

带有 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"))
Run Code Online (Sandbox Code Playgroud)


Car*_*arr 8

这个讨论已经有一段时间了,而且@Alexander T.的回答提供了一个很好的指导,可以跟随像我这样的反应.而且我将分享更多关于这个讨论的知识,以解决新手在开始时可能遇到的一个常见问题.

componentWillReceiveProps(nextProps),从官方文件:

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

我们可以得出结论,这里是我们处理参数的地方,这些参数可能来自父组件的url或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 (...)
  }
}
Run Code Online (Sandbox Code Playgroud)

更新

componentWillReceiveProps() 将被弃用.

以下是生命周期中的一些方法(Doc中的所有方法),我认为这与在一般情况下部署API有关: 在此输入图像描述

通过参考上图:

  • 在中部署API componentDidMount()

    在这里进行API调用的正确方案是该组件的内容(来自API的响应)将是静态的,componentDidMount()仅在组件安装时触发一次,甚至新的道具从父组件传递或具有引导操作re-rendering.
    该组件确实检查差异以重新渲染但不重新安装.
    来自doc的引用:

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


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

我们应该注意到,有两种组件更新,setState() 在当前组件不会导致此方法引发,但再渲染或新道具父组件做.我们可以发现这种方法在安装时也会发射.

如果我们想要像模板一样使用当前组件,那么这是部署API的合适位置,而API的新参数是来自父组件的道具.
我们从API收到不同的响应,并state在此处返回新的更改此组件的内容.

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


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

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

扩展前面的示例:
显示Car的详细信息的组件可能包含此车系列的列表,如果我们要查看2013年的生产,我们可以点击或选择或...列表项引导第一个setState()反映这个此组件中的行为(例如突出显示列表项),并在下面componentDidUpdate()我们使用新参数(state)发送请求.得到回复后,我们setState()再次呈现Car详细信息的不同内容.为了防止以下componentDidUpdate()引起无限循环,我们需要通过prevState在此方法的开头使用来比较状态,以决定我们是否发送API并呈现新内容.

这种方法真的可以像static getDerivedStateFromProps()道具一样使用,但需要props通过利用来处理变化prevProps.我们需要配合componentDidMount()处理初始API调用.

来自doc的引用:

...只要您将当前道具与之前的道具进行比较,这也是进行网络请求的好地方......


Hit*_*ahu 7

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

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  
                        });
        }
      });
  };
Run Code Online (Sandbox Code Playgroud)

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
            })
          );
}
Run Code Online (Sandbox Code Playgroud)

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

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

  componentDidMount() {
    this.fetchData ();
  }
Run Code Online (Sandbox Code Playgroud)

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

   {this.state.isLoading && <LinearProgress />}
Run Code Online (Sandbox Code Playgroud)


Nha*_*ran 6

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