在对钩子做出反应时,如何遍历列表并仅获取某些项?

时间:2019-12-20 18:07:07

标签: javascript reactjs create-react-app react-bootstrap

我有一个列表,该列表显示在表中,然后根据复选框更新最后一列。现在,我只想获取已标记为选中的值。我已经从控制台日志中确认,最后一列正在使用正确的值进行更新。

这是我要添加到的代码:

  const addToPool = () => {
    setDiePool([
      ...diePool,
      {
        dp1 : poolCount,
        dp2 : diceType,
        dp3 : diceNumber,
        dp4 : diceAdjuster,
        dp5 : diceAlias,
        dp6 : poolStatus
      }
    ]);
    setPoolCount(poolCount+1);
  };

这是我用来更新状态为“已检查”的列的代码。该列表可能包含多个已检查的项目。选中该项目时,不运行计算,而是单击另一个按钮。

  const handleSelectItem = (die) => {
    setDiePool(diePool.map(diePool => {
         if(diePool.dp1 !== die.dp1) return diePool
         if(diePool.dp6 == "checked"){
          return {...diePool, dp6: ""}
         }
         else {
          return {...diePool, dp6: "checked"}
         }         
    }))
  };

dp6是包含“已检查”或“”的字段。现在,当我单击“最终结果”按钮时,我想获取已“检查”的记录并使用这些值进行计算。我想根据得到的值返回最终的计算结果。我怎么做?

**说明: 我想要一个按钮:

<Button onClick={showResult}>Show Results</Button>

,然后使用列表的值执行计算,而无需更改列表。

  const showResults = () => {
    //Run through the diePool list and add up the values if dp6 == checked
    //Return value, without altering the list
  };

我尝试了这个,但是它不喜欢if语句:

  const showResult = diePool.map((die) => 
    //if(die.dp6 == "checked"){
      <li>{die.dp1}</li>
    //}
  );

**更新 我也许能够将地图转换为数组,然后遍历它。仍在研究解决方案。

  const dResult = Object.values(diePool);
  for(let x = 0; x < dResult.length; x++){
    if (dResult[x].dp6 == "checked"){
      //console.log(dResult[x].dp1);
    }
  }

4 个答案:

答案 0 :(得分:0)

import { NewsService } from './news.service';
//component declarations and imports ...
export class NewsComponent implements OnInit {
   list: any[];
   constructor(private newsService: NewsService){}

   buttonClicked(){
      this.newsService.Getlist().subscribe(list => {
        this.list = list;
        console.log(this.list);
      })
   }
}

答案 1 :(得分:0)

尝试:

const handleSelectItem = (die) => {
    setDiePool(diePool.map(diePool => {
         if(diePool.dp1 !== die.dp1) return [...diePool]
         else if(diePool.dp6 == "checked"){
          return [...diePool, {dp6: ""}]
         }
         else {
          return [...diePool, {dp6: "checked"}]
         }         
    }))   };

答案 2 :(得分:0)

它不喜欢RecyclerView,因为您省略了if的缩写:

{}

这使得它为什么无效更加明显。

这是重新格式化功能以使其正确的一种方法:

const showResult = diePool.map((die) => {
  return (
    if(die.dp6 == "checked"){
      <li>{die.dp1}</li>
    }
  )
});

一行中的另一个选项是:

const showResult = diePool.map((die) => {
  if(die.dp6 == "checked"){
    return <li>{die.dp1}</li>
  }
});

但是,这不适用于您提供的按钮,因为事件处理程序期望返回void,并且此函数返回要呈现的JSX。

您可以将按钮重构为具有以下某种功能:

const showResult = diePool.filter(die => die.dp6 == "checked").map(die => <li>{die.dp1}</li>);

答案 3 :(得分:0)

我看到您可以实施两种可能的解决方案。

一种方法是添加一个对象作为状态变量,并跟踪已检查元素的索引。您可以在“ handleSelectItem”中为此添加逻辑。至于为什么一个对象,仅仅是因为它删除和检查存在的速度更快。然后,您的最终结果函数将遍历此对象的Object.keys,并对检查的每个diePool元素进行处理。

另一个是您的建议,使用diePool.map和if,但是添加了一些逻辑以不修改diePool数组的对象(请注意,修改数组内部的对象会更改对象的原始对象)原始数组)。另外,如果碰巧有dp1,dp2等对象,请格外小心。

关于最终结果函数的作用,如果没有更多关于要计算的内容的信息,我将无济于事。希望您很容易发现解决了跟踪问题。


顺便说一下,这段代码重复了变量的“ diePool”名称。可能由于范围而起作用,但是出于可读代码的考虑,我将映射变量的名称更改为“ item”,“ diePoolItem”或类似名称。

  const handleSelectItem = (die) => {
    setDiePool(diePool.map(diePool => {
         if(diePool.dp1 !== die.dp1) return diePool
         if(diePool.dp6 == "checked"){
          return {...diePool, dp6: ""}
         }
         else {
          return {...diePool, dp6: "checked"}
         }         
    }))
  };