【问题标题】:React: How do I move my ajax api call into a separate component?React:如何将我的 ajax api 调用移动到一个单独的组件中?
【发布时间】: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方法了。

标签: javascript ajax api reactjs refactoring


【解决方案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
                });
              });
          }
      

      现在可以了!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-05
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 2019-09-20
        • 2021-01-26
        • 1970-01-01
        • 2013-08-14
        相关资源
        最近更新 更多