Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/420.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在react中处理纯功能组件中的Ajax?_Javascript_Ajax_Reactjs_Purely Functional - Fatal编程技术网

Javascript 如何在react中处理纯功能组件中的Ajax?

Javascript 如何在react中处理纯功能组件中的Ajax?,javascript,ajax,reactjs,purely-functional,Javascript,Ajax,Reactjs,Purely Functional,我试图把所有的组件都写成纯函数,但现在我遇到了麻烦。我有一个看起来有点像下面的组件。问题是,ajax请求的结果会导致一个重新加载,这会导致另一个ajax请求,这样就有了无限循环。如何妥善处理? const PageProductFunnel = function (props) { const agent = ajaxagent; var list = []; agent.get(`https://mylist.com/${productSKU}`).then((res) =>

我试图把所有的组件都写成纯函数,但现在我遇到了麻烦。我有一个看起来有点像下面的组件。问题是,ajax请求的结果会导致一个重新加载,这会导致另一个ajax请求,这样就有了无限循环。如何妥善处理?

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>
  );
};
const pageProduct漏斗=函数(道具){
const agent=ajaxagent;
var列表=[];
探员(`https://mylist.com/${productSKU}`)。然后((res)=>{
列表=资源数据;
});
返回(
{product.name}
);
};

您可以采取以下几种方法:

  • 全局获取异步数据,而不是在组件的呈现内部
  • 不要对此组件使用纯函数,并将异步挂钩到生命周期方法中

  • 为此,您需要使用有状态的组件

    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>
        );
      }
    };
    
    类PageProduct.Component{
    状态={
    “名单”:[]
    }
    组件将安装(){
    探员(`https://mylist.com/${productSKU}`)。然后((res)=>{
    this.setState({list:res.data})
    });
    }
    渲染(){
    返回(
    {product.name}
    );
    }
    };
    
    编辑请阅读评论。经过更多的考虑,我决定实施达沃林·鲁舍夫的第一个建议。我自己的解决方案有效,但他的更好


    谢谢你的建议,但它们并不能解决问题。到目前为止,我所有的代码都是纯代码,我真的想坚持下去。在我的例子中,在全局级别进行调用不会改变任何东西,因为响应仍然会导致渲染

    我更改了代码,使列表成为状态的一部分(我正在使用redux)。只有当列表为空时,我才会执行ajax调用。每当我知道需要新数据时,我都会在页面再次呈现之前清除旧列表

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

    进行ajax调用的更好的生命周期钩子是componentDidMount()。如果您特别喜欢使用纯组件,那么您也可以在纯组件中使用

    class Sample extends PureComponent{
      //react implement ShouldComponentUpdate for us which does shallow comparison
      componentDidMount(){
         //api call here
      }
     }
    
    但是你不能只使用pureComponent来构建react应用程序,因为如果你不想通过检查状态来停止更新生命周期,那么你就不能使用pureComponent,因为pureComponent只对我们进行浅层检查,它会检查组件中的所有状态


    我们应该在项目中平衡有状态、纯组件和无状态

    全局获取将导致重新渲染,但不会导致无休止的递归获取,这是您的问题。至于您希望只使用功能组件,祝您好运。这就是为什么它们不是唯一可用的组件类型的原因。嗯,是的。你的评论给了我另一个想法。基本上,问题在于调用的调用是在渲染函数本身内启动的。我自己的解决方案也不是很好。通过将ajax调用移出此范围并从其他事件调用它(打开页面的单击即可),我可以防止这种情况。