【问题标题】:React: Syntax for calling setState in Switch ReturnReact:在 Switch Return 中调用 setState 的语法
【发布时间】:2016-12-15 20:39:13
【问题描述】:

很难弄清楚我在这里做错了什么......而且我敢肯定这是我错过的一些简单的事情。只要传递到此 switch 调用的数据与每个类别匹配,就尝试在状态上增加计数器,但由于某种原因,计数器不会增加...

countCategories(cart) {
cart.map(function(item){
  switch (item.type) {
      case "beverage": return () => { this.setState({
        countBeverage: this.state.countBeverage + 1
      }); }
      case "fruit": return () => { this.setState({
        countFruit: this.state.countFruit + 1
      }); }
      case "vegetable": return () => { this.setState({
        countVegetable: this.state.countVegetable + 1
      }); }
      case "snack": return () => { this.setState({
        countSnack: this.state.countSnack + 1
      }); }
      default: return console.log("unknown category");
    };
}); }

我也尝试过这种方式,但是当我这样称呼它时,我认为我没有提到“this”:

countCategories(cart) {
cart.map(function(item){
  switch (item.type) {
      case "beverage": return this.setState({
        countBeverage: this.state.countBeverage + 1
      })
      case "fruit": return this.setState({
        countFruit: this.state.countFruit + 1
      })
      case "vegetable": return this.setState({
        countVegetable: this.state.countVegetable + 1
      })
      case "snack": return this.setState({
        countSnack: this.state.countSnack + 1
      });
      default: return console.log("unknown category");
    };
}); }

非常感谢您的帮助!

【问题讨论】:

  • 何时调用countCategories
  • 先计算值,再设置..

标签: reactjs


【解决方案1】:

就这样吧,伙计:

let food = [{type: "snack"},{type: "snack"},{type: "snack"},{type: "snack"}, 
            {type: "veggi"},{type: "veggi"},{type: "veggi"},{type: "veggi"}]

let foodCount = {
   veggiCount: this.state.veggiCount || 0, 
   snackCount: this.state.snackCount || 0,
   beefCount:  this.state.beefCount || 0,
   fruitCount: this.state.fruitCount || 0
};

food.map(item => foodCount[item + "Count"]++ )
this.setState(foodCount)

这里重要的是,设置状态 1. 一次,2. 计算完成时。避免在循环或迭代中设置状态,如 for(...) setState()

【讨论】:

    【解决方案2】:

    假设您正在调用绑定到组件的countCategoriesthis 的值是组件),在您的第一个代码中应该可以工作,您可以将映射函数更改为箭头函数,因此它保持countCategories 函数的 this 值。我注意到的另一件奇怪的事情是,您通过返回应该更改状态的函数来创建函数数组,而不是实际更改状态:

    countCategories(cart) {
      // Notice the change in the next line
      cart.map(item => {
        switch (item.type) {
          case "beverage": 
            // Set the state instead of returning a function that sets the state
            this.setState({
              countBeverage: this.state.countBeverage + 1
            });
            break;
          case "fruit": 
            this.setState({
              countFruit: this.state.countFruit + 1
            });
            break;
          case "vegetable": 
            this.setState({
              countVegetable: this.state.countVegetable + 1
            });
            break;
          case "snack": 
            this.setState({
              countSnack: this.state.countSnack + 1
            });
            break;
          default: 
            console.log("unknown category");
            break;
        };
      }); 
    }
    

    【讨论】:

      【解决方案3】:

      这里的一个重要考虑因素是setState 是异步的,因此您无法在同一执行周期中读取值并对其进行递增。相反,我建议创建一组更改,然后将它们应用到单个 setState 中。

      下面我使用map 来迭代购物车并增加存储在克隆副本中的状态值(因为this.state 应该被认为是不可变的)。然后一旦完成,状态就会更新。

      let newState = Object.assign({}, this.state);
      cart.map((item) => {
        // adapt type to state string -> snack to countSnack
        const type = item.type.replace(/^(.)/, (s) => 'count' + s.toUpperCase());
        newState[type] = (newState[type] || 0) + 1;
      });
      
      this.setState(newState);
      

      详情请参阅Component API documentation 内的注释

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多