简体   繁体   English

如何在纯功能组件中处理Ajax反应?

[英]How to handle Ajax in pure function components in react?

I'm trying to write all my components as pure functions, but now I run into trouble. 我试图将所有组件写为纯函数,但现在遇到麻烦了。 I have a component that looks somewhat like below. 我有一个看起来像下面的组件。 Trouble is, the result of the ajax request causes a rerender, which causes another ajax request, and there you have your infinite loop. 麻烦的是,ajax请求的结果导致了重新渲染,这又导致了另一个ajax请求,并且您陷入了无限循环。 How to properly handle this? 如何正确处理呢?

const PageProductFunnel = function (props) {
  const agent = ajaxagent;
  var list = [];

  agent.get(`https://mylist.com/${productSKU}`).then((res) => {
    list = res.data;
  });

  return (
    <div>
      <div className="cell">
        <article className="article">
          <h1 className="article-title">{product.name}</h1>
          <FunnelStep {...props} list={list} />
          <ButtonAddToCart product={product} />
        </article>
      </div>
    </div>
  );
};

There are few approaches you can take: 您可以采取几种方法:

  1. fetch async data globaly, not inside render of the component 全局获取异步数据,而不是在组件的内部渲染
  2. Do not use pure function for this component, and hook async into life cycle methods 不要为此组件使用纯函数,而将异步挂钩到生命周期方法中

You need to use stateful components for this. 您需要为此使用stateful组件。

class PageProductFunnel extends React.Component {
  state = {
    "list": []
  }

  componentWillMount () {
    agent.get(`https://mylist.com/${productSKU}`).then((res) => {
      this.setState({list:res.data})
    });
  }

  render () {
    return (
      <div>
        <div className="cell">
          <article className="article">
            <h1 className="article-title">{product.name}</h1>
            <FunnelStep {...props} list={this.state.list} />
            <ButtonAddToCart product={product} />
          </article>
       </div>
      </div>
    );
  }
};

EDIT Please read the comments. 编辑请阅读评论。 After some more considerations, I've decided to implement Davorin Ruševljans first suggestion. 经过更多考虑之后,我决定实施DavorinRuševljans的第一个建议。 My own solution works but his is better. 我自己的解决方案有效,但他的效果更好。


Thanks for the suggestions but they really don't solve the problem. 感谢您的建议,但实际上并不能解决问题。 All my code is pure so far, and I really want to stick with it. 到目前为止,我所有的代码都是纯净的,我真的想坚持下去。 Making the call on a global level doesn't change anything in my case as the response would still cause a render. 在我看来,在全局范围内进行调用不会有任何改变,因为响应仍然会导致渲染。

I changed the code so that the list is part of the state (I'm using redux). 我更改了代码,使列表成为状态的一部分(我正在使用redux)。 Only if the list is empty, I perform the ajax call. 仅当列表为空时,我才执行ajax调用。 Whenever I know I expect new data, I clear the old list before the page renders again. 每当我知道需要新数据时,我都会在页面再次呈现之前清除旧列表。

if (props.list.length === 0) {
  agent.get(`https://mylist.com/${productSKU}`).then((res) => {
    props.setList(res.data);
  });
}

The better life cycle hook to do an ajax call is componentDidMount (). 进行ajax调用的更好的生命周期挂钩是componentDidMount ()。 If you are so specific to use pure component you can use in pure Component as well. 如果您对使用纯组件非常专一,则也可以在纯组件中使用。

class Sample extends PureComponent{
  //react implement ShouldComponentUpdate for us which does shallow comparison
  componentDidMount(){
     //api call here
  }
 }

But You can't build a react app using only pureComponent, Because if there is a case where you wan't to stop the updation life cycle by checking the state, then you can't do that using PureComponent Because Pure component does only shallow checking for us and it checks for all the states in the component. 但是您不能仅使用pureComponent来构建React应用程序,因为如果您不想通过检查状态来停止更新生命周期,那么您就不能使用PureComponent来做到这一点,因为Pure组件只会使检查我们,并检查组件中的所有状态。

We should balance stateful, PureComponent, Stateless among the project. 我们应该在项目之间平衡有状态,PureComponent和无状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM