通过 React AJAX 调用避免重复代码

Avoiding repetitive code with React AJAX calls

我在一个非常简单的应用程序上使用 React 和 React Router。

路由模式:

   <Route path='/' component={Layout}>
      <IndexRoute component={Home} />
      <Route path='/users' component={Users} />
      <Route path='/posts' component={Posts} />
   </Route>

我想做的是编写一个函数,帮助避免在每个组件中重复 AJAX 调用,因为它几乎是相同的代码。

我的 State/AJAX 配置,在 'Users' 组件中调用:

   constructor(props) {
      super(props);
      this.state = {
         users: []
      };
   }
   componentDidMount() {
      axios.get('https://jsonplaceholder.typicode.com/users')
         .then( response => {
            const users = response.data
            this.setState({ users });
         });
   }

我想创建一个函数,它接受端点作为参数,然后可以在每个组件中重复使用,只需换出端点...就像这样:

function(endpoint) {
   axios.get({`https://jsonplaceholder.typicode.com/${endpoint}`})
   // rest of the AJAX call...
}

但是我不知道在哪里定义这个函数。根据我的路由结构 'Layout',它会在父组件中吗?如果是这样,我如何将该函数作为道具传递给子组件?我知道如何使用嵌套组件执行此操作,但不知道如何使用嵌套路由...

我的布局组件:

export default class Layout extends Component {

render() {
   return (
   <div>
      <header><h1>Testing with react-router</h1></header>
      <Nav />
      <div className='pc-content container'>
         {this.props.children}
      </div>
      )
   }
}

我确信 Redux/Flux 有更有效的方法可以做到这一点,但我没有先尝试。

此外(这是一个稍微不同的问题),是否有一种简单的方法来缓存响应负载,以便每次呈现组件时都不会再次请求数据?

任何help/pointers赞赏。


更新(@Lukas Liesis)

已提取对 call_helper.js 的 ajax 调用:

import axios from 'axios'

const call = (endpoint) => {
   axios.get(`https://jsonplaceholder.typicode.com/${endpoint}`)
      .then( response => {
         endpoint = response.data
         this.setState({ endpoint });
      });
}

export {call};

并将其拉入 Users 组件:

import call from '../js/call_helper'

现已将 componentDidMount 更新为:

componentDidMount() {
      call('users')
      // axios.get('https://jsonplaceholder.typicode.com/users')
      //    .then( response => {
      //       const users = response.data
      //       this.setState({ users });
      //    });
   }

控制台日志:Users.js:66 Uncaught TypeError: (0 , _call_helper2.default) is not a function

只需将它添加到某个单独的文件中,并在需要时随时包含它。

您可以根据需要命名文件,但假设它是 call_helper.js

const call = (endpoint) => {
   return new Promise((resolve, reject) => {
      axios.get({`https://jsonplaceholder.typicode.com/${endpoint}`})
      // rest of the AJAX call...
      // when ajax call is done, just call:
      resolve(result);
      // if some error, then:
      reject(error);
   })
};

export {call};

现在您可以使用

将其包含在任何组件中
include {call} from './path/to/file/call_helper';

并通过简单调用在组件中的任何位置使用它:

call('some_endpoint')
  .then(result => {
     // do something with result
  })
  .catch(e => {
    // do something with error
  });

你会在这里找到你正在寻找的实现: https://github.com/mzabriskie/axios/issues/320(查看 mikechabot 评论)