React:如何将我的 ajax api 调用移动到一个单独的组件中?

Posted

技术标签:

【中文标题】React:如何将我的 ajax api 调用移动到一个单独的组件中?【英文标题】:React: How do I move my ajax api call into a separate component? 【发布时间】:2016-09-27 08:20:54 【问题描述】:

这是一个运行良好的典型容器组件:

const API = 'https://randomuser.me/api/?results=5';
class App extends Component 

    constructor(props) 
      super(props);
      this.state =  profiles: [] ;
    

    componentDidMount() 
      this.fetchProfiles();
    

    fetchProfiles() 
      let url = API;
      fetch(url)
        .then( (res) => res.json() )
        .then( (data) => 
          let results = data.results;
          this.setState(
            profiles: results 
          );
        )
        .catch( (error) => console.log('Oops! . There Is A Problem', error) );
    

    render() 
      // rendering child component here
    


export default App;

我现在要做的是将fetchProfiles 函数移动到一个单独的api 组件中。

所以我在项目的api 文件夹中创建了一个profiles.js 文件:

const API = 'https://randomuser.me/api/?results=5';

export function fetchProfiles() 
  let url = API;
  fetch(url)
  .then( (res) => res.json() );

现在我的主要组件导入它并像这样使用它:

import  fetchProfiles  from '../api/profiles.js';


const API = 'https://randomuser.me/api/?results=5';
class App extends Component 

    constructor(props) 
      super(props);
      this.state =  profiles: [] ;
    

    componentDidMount() 
      fetchProfiles.then((data) => 
        let results = data.results;
          this.setState(
            profiles: results 
          );
      );
    

  // render call etc

但是当我像这样在componentDidMount 中运行调用时,我得到了这个错误:Uncaught TypeError: _profiles.fetchProfiles.then is not a function。我正在尝试与 then 链接,因为 fetch api 返回 res.json() 作为承诺。

我尝试将fetchProfiles 包装在一个外部函数中,也包括在一个新的承诺中!但没有任何效果!!我在这里做错了什么?请帮助进行此重构。

【问题讨论】:

你需要自己返回fetch(url),所以你会返回一个promise,然后你就可以使用then方法了。 【参考方案1】:

我曾经做过一个类似的应用程序,我将 API 调用与上下文分开(我使用了上下文 API btw),而不是返回 fetch 函数并处理上下文中的异步调用,我处理了 API 上声明的函数上的所有内容并且在上下文中只收到了结果,这似乎有点复杂,但它简化了上下文的数据处理和另一侧的所有数据获取登录,我也使用 axios 进行 API 调用,但它很容易交换使用 fetch one(axios 可以更好地处理错误,例如处理超时或服务不可用)

关于profiles.js:

import axios from 'axios';

const API = 'https://randomuser.me/api/?results=5';    

export const fetchProfiles = async () => 
    let url = API;
    try
      const response = await axios.get(url)
      const data = response.data
      return data
    catch(error) 
      console.log('failed to fetch Profiles')
      throw Error(error)
    

上下文:

import  fetchProfiles from "../API/profiles";

const getProfiles = async () =>
  const result = await fetchProfiles();
  this.setState(
    profiles: result
  );

【讨论】:

【参考方案2】:

你需要自己返回fetch(url),所以你会返回一个promise然后你可以使用then方法:

const API = 'https://randomuser.me/api/?results=5';

export function fetchProfiles() 
  let url = API;

  // return the promise itself
  return fetch(url).then( (res) => res.json() );

【讨论】:

【参考方案3】:

我解决这个问题的方法是返回 fetch(url) 本身:

const API = 'https://randomuser.me/api/?results=5';

export function fetchProfiles() 
    let url = API;
    return fetch(url)
      .then( (response) => response.json() );

然后在容器组件中:

    componentDidMount() 
      fetchProfiles()
        .then( (data) => 
          let results = data.results;
          this.setState(
            profiles: results
          );
        );
    

现在可以了!!

【讨论】:

以上是关于React:如何将我的 ajax api 调用移动到一个单独的组件中?的主要内容,如果未能解决你的问题,请参考以下文章

如何保护移动和 AJAX 调用的 JSON RESTful API?

Phonegap android ajax调用在浏览器中工作,而不是在移动设备上

使用 fetch API 时在 AJAX 调用期间显示微调器

如何使用 React + Webpack 应用程序存储和访问我的 API 密钥?

如何在前端的 Javascript Ajax API 调用中隐藏我的 JWT 令牌?

React useEffect 调用 API 的时间太多,当我的组件渲染时,如何将 API 调用限制为一次?