【问题标题】:Fill state property after ajax requestajax请求后填充状态属性
【发布时间】:2018-07-19 09:15:48
【问题描述】:

我遇到了reactjs 的问题。 我想将另一个属性 (productGroups) 添加到现有状态 (this.state.mainProductGroups - 输入 object array)。 所以我想在数组中找出对应的条目并将新属性添加到其中。 这是我的功能:

getProductGroups(mainProductGroupId) {
    $.ajax({
        type: "POST",
        context:this,
        dataType: "json",
        async: true,
        url: "ajax.php",
        data: ({ 
            requestType: 'getProductGroups',
            countryID: this.state.countryObject.countryNo,
            languageID: Language[this.state.currentLanguage].languageNo,
            mainProductGroupID: mainProductGroupId,
        }),
        success: function (data) {
           let mainProductGroups = this.state.mainProductGroups;
           let mainPGFound = false;
           let mainPG = mainProductGroups.filter(mainProductGroup => mainProductGroup.id == mainProductGroupId);
           mainPG.productGroups = data.productGroups;
           this.setState({
              mainProductGroups: mainProductGroups,
           });

        }
    });
  }

这是this.state.mainProductGroups的数据示例:

现在的问题是,productsGroup 属性没有被填充。 ajax 请求返回正确的值(也输入object array)。为什么不更新?有没有问题,因为属性productGroups 的初始值为string,现在我想用object array 类型覆盖它? 难道我做错了什么?我是不是想错了? 感谢您的帮助!

【问题讨论】:

    标签: arrays reactjs state


    【解决方案1】:

    将您的成功处理程序更改为此

     success: function (data) {}
    

    从这里

     success: (data)=> {}
    

    查看您在编写function 时设置状态的时间,它是回调中this 上下文的新范围。所以它不会从上下文中找到thisthis。你需要的是一个带有箭头函数的词法作用域。在这种情况下,您需要什么。

    这里的问题是

    通常,如果我们正在编写 ES5,我们会使用类似 Function.prototype.bind 从另一个作用域中获取 this 值 更改函数的执行上下文。这将主要用于 不同范围内的回调。

    查看更多here

    【讨论】:

    • 感谢您的解释。很高兴知道其中的区别,但事实证明这是一个不同的问题。我可以将它与您提出的解决方案一起使用,也可以与旧解决方案一起使用(function(data) {}。我认为,这是由于 ajax 属性context:this。你说 jQuery,使用哪个上下文。
    【解决方案2】:

    Manoz 关于this 在常规函数中丢失上下文是正确的。我想更进一步,实际上将该函数提取到它自己的组件方法中,所以你最终会得到这样的结果:

    updateMainProductGroups = data => {
       const { mainProductGroups } = this.state;
       const mainPG = mainProductGroups.find(mainProductGroup =>
            mainProductGroup.id === mainProductGroupId
       );
       mainPG.productGroups = data.productGroups;
    
       this.setState({ mainProductGroups });
    }
    
    getProductGroups(mainProductGroupId) {
        $.ajax({
            type: "POST",
            context: this,
            dataType: "json",
            async: true,
            url: "ajax.php",
            data: ({ 
                requestType: 'getProductGroups',
                countryID: this.state.countryObject.countryNo,
                languageID: Language[this.state.currentLanguage].languageNo,
                mainProductGroupID: mainProductGroupId,
            }),
            success: updateMainProductGroups
        });
    }
    

    注意:我删除了这行let mainPGFound = false; 似乎没有在这个函数中使用,我还将filter 更改为find,因为您似乎想要对返回的对象进行操作,并且@987654326 @ 实际上会给你一个包含该对象的数组。

    【讨论】:

      【解决方案3】:

      我的最终解决方案是这个。

      getProductGroups(mainProductGroupId) {
          $.ajax({
              type: "POST",
              context:this,
              dataType: "json",
              async: true,
              url: "ajax.php",
              data: ({ 
                  requestType: 'getProductGroups',
                  countryID: this.state.countryObject.countryNo,
                  languageID: Language[this.state.currentLanguage].languageNo,
                  mainProductGroupID: mainProductGroupId,
              }),
              success: (data) => {
                let mainProductGroups = this.state.mainProductGroups.map((mainProductGroup) => {
                  if(mainProductGroup.id === mainProductGroupId) {
                    mainProductGroup.productGroups = data.productGroups;
                  }
                  return mainProductGroup;
                });
                this.setState({
                   mainProductGroups: mainProductGroups,
                });
              }
          });
        }
      

      我认为,原因是我在第一个解决方案中根本没有更改状态属性mainProductGroups。现在它工作正常。谢谢大家的帮助。

      【讨论】:

        【解决方案4】:

        改变

        this.setState({
            mainProductGroups: mainProductGroups,
        });
        

        this.setState({
           mainProductGroups: mainPG.productGroups
        });
        

        【讨论】:

        • 不,这不是解决方案,因为mainProductGroups 包含多个 mainPG。在您的解决方案中,我将只用一个 mainPG 覆盖它。
        • 问题是你将你的状态设置为mainProductGroups,你永远不会编辑它。您想将data.productGroups 添加到您的州,我说得对吗?
        • 但是当我得到数组的单个对象时,我使用的是mainProductGroups 的引用。所以我想,我不需要编辑状态对象本身,对吗?
        • 通常你必须这样做
        • 我认为,最后你的提示是对的,我没有编辑 mainProductGroups 状态属性。
        猜你喜欢
        • 2021-10-20
        • 2011-12-11
        • 2021-10-18
        • 1970-01-01
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-07
        相关资源
        最近更新 更多