【问题标题】:Looping through a Map in React在 React 中循环遍历地图
【发布时间】:2018-08-01 16:48:48
【问题描述】:

我有一个Map 对象:

let dateJobMap = new Map();

for (let jobInArray of this.state.jobs) {
  let deliveryDate: Date = new Date(jobInArray.DeliveryDate);
  let deliveryDateString: string = deliveryDate.toLocaleDateString("en-US");

  if (dateJobMap.has(deliveryDateString)) {
    let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
    jobsForDate.push(jobInArray);
  }
  else {
    let jobsForDate: IDeliveryJob[] = [jobInArray];
    dateJobMap.set(deliveryDateString, jobsForDate);
  }
}

在我的render 方法中,我想为值数组中的每个交付作业调用一个 TruckJobComp 对象以显示它:

        <div className={ styles.column }>
          <p className={ styles.description }>{escape(this.props.description)}</p>

          {
            dateJobMap.forEach(function(jobsForDate, dateString) {
              jobsForDate.map(job => (
                <TruckJobComp job = { job } />
              ))
            })
          }
        </div>

这似乎应该工作,但没有。它从不创建 TruckJobComp。我在我的Map 上进行.forEach 迭代,对于每个valuearray,我使用.map 来获取单个作业对象以发送到TruckJobComp 对象。

当我创建一个临时 array 以从最后一个循环中获取作业时:

let tempJobs: IDeliveryJob[];

并在循环中添加:

  if (dateJobMap.has(deliveryDateString)) {
    let jobsForDate: IDeliveryJob[] = dateJobMap.get(deliveryDateString);
    jobsForDate.push(jobInArray);

    tempJobs = jobsForDate;
  }

然后在渲染中使用array

          <div className={ styles.column }>
            <p className={ styles.description }>{escape(this.props.description)}</p>
            {
              tempJobs.map(job => (
                <TruckJobComp job = { job }/>
              ))
            }
          </div>

它按预期显示。

我在 Visual Studio Code 中有警告:

Warning - tslint - ...\TruckDeliverySchedule.tsx(104,38): error no-function-expression: Use arrow function instead of function expression

我知道的不够多,无法理解。第 104 行对应:

dateJobMap.forEach(function(jobsForDate, dateString) {

我对此很陌生,所以我不能 100% 确定其中大部分是如何工作的。只是想把我学到的东西放在一起,让事情发挥作用。

第二次编辑:

{escape(this.props.description)}

{
  [...dateJobMap.keys()].map(jobsForDate => // line 154
    jobsForDate.map(job => (
      <TruckJobComp job = { job } />
    ))
  )
}

产生错误:

[09:06:56] Error - typescript - src\...\TruckDeliverySchedule.tsx(154,27): error TS2461: Type 'IterableIterator<any>' is not an array type.

【问题讨论】:

    标签: javascript reactjs typescript


    【解决方案1】:

    dateJobMap.forEach(...) 返回undefined,因此无法映射到元素集合。

    出于兼容性目的,ES6 映射具有 forEach 方法(通常首选 for..of 来迭代可迭代对象)并且没有 map 方法。映射应先转换为数组,然后才能映射到元素。由于不使用值,因此只需要检索键:

      {
        [...dateJobMap.keys()].map(jobsForDate =>
          jobsForDate.map(job => (
            <TruckJobComp job = { job } />
          ))
        )
      }
    

    【讨论】:

    • 我对 typescript/javascript 开发相当陌生(我已经做了 7 年的 iOS),我很抱歉,我不完全理解您提供的示例代码。 ... 是什么?为什么...dateJobMap.keys() 是这样括起来的?而且我不感激使用.forEach,这只是我发现的第一个。
    • 如前所述,它将地图转换为数组。 dateJobMap.keys() 是返回an iterableMap 方法,... spread syntax[] 数组字面量一起使用时将可迭代对象转换为数组。s
    • 感谢您的链接。还有很多要学的。我尝试了代码块,但出现错误;我更新了问题。这就是我要求澄清的原因,尽管这可能是我应该已经知道的事情的简写。
    • 我没有注意到问题上的 typescript 标签。问题是特定于 TS 的。请参阅 stackoverflow.com/a/46605880/3731501stackoverflow.com/a/43964577/3731501 。您应该启用downlevelIteration 编译器选项或将[...dateJobMap.keys()] 替换为Array.from(dateJobMap.keys())
    • @JuaniCondina Set/map 迭代器迭代在该上下文中有意义的事物,[...map][...map.entries()] 相同,[...set][...set.values()] 相同。
    【解决方案2】:

    所有这些警告的意思是,不要使用语法function(jobsForDate, dateString) {},而应该使用语法(jobsForDate, dateString) =&gt; {}

    原因可能是 this 在箭头函数和函数表达式中的作用域。见this post.

    我猜测您的第一种方法不起作用但您的第二种方法起作用的原因是 forEach 实际上并没有返回一个数组,如果确实如此,在 forEach 内调用 map 将返回一个数组数组(但同样,它没有)。不确定 React 会如何处理,但 React 确实知道如何处理单个数组,这是您最后一种方法返回的结果。

    【讨论】:

    • .forEach 本身不会返回数组,但它应该返回 Mapvalue 数组。我已经通过 console.loging 在渲染方法之外确认了这一点。
    • 如果您查看.forEach 方法的文档,您会看到它返回undefineddeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 您可以在我在 REPL 中运行的这个简单示例中看到这一点。请注意,当您检查 a 的值时,您会得到 Map,但是当您检查 b 时,您什么也得不到,即未定义。 imgur.com/SjDtUIc
    • 贾里德,你的例子是对的。当我在渲染和 console.log 变量之前执行“.forEach”循环时,它们具有值。 JobsForDate 以数组形式记录。我会更新问题。
    • 经过更多的思考和玩弄,我明白你在说什么。虽然我需要的数组在循环范围内可用,但 .forEach 不会向 &lt;div&gt; 返回任何内容以显示。感谢您的帮助。
    猜你喜欢
    • 2012-04-19
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多