【问题标题】:forEach over es6 Map in JSXJSX 中的 forEach over es6 Map
【发布时间】:2016-06-06 01:29:35
【问题描述】:

我有一个使用array.map 渲染组件的javascript 数组。我将此数组切换为 es6 Map,以便能够使用键值对更轻松地查找项目,并在 Map 上从 .map 切换为 forEach。在 forEach 内部,我调用了一个返回 React 组件的渲染方法,但它没有被渲染。如何在forEach 中渲染组件?

<div className='gallery__items'>
    {resultsByGuid.forEach((result, index) => {
        key++;
        this.renderGalleryItem(result, key);
    })} 
</div>

这里是 renderGalleryItem 方法:

renderGalleryItem = (item, index) => {
    const { gridItemSelected, itemThumbnailRequested } = this.props;
    return (
        <GalleryItem
            key={index}
            item={item}
            onClick={gridItemSelected}
            fetchThumbnailFunc={itemThumbnailRequested}
        />
    );
};

我知道 forEach 不会返回任何内容,但这是否意味着我无法在其中进行渲染?

【问题讨论】:

  • 您如何将该 html 字符串存储/附加到您在 forEach 之后注入的变量中?
  • 使用Map.prototype.values() 方法。
  • 那么,JSX 需要一个数组吗?然后使用Array.from(resultsByGuid) 并从那里使用.map
  • @John 请不要仅仅因为它们主要是关于框架或库而不是语言本身而从 JavaScript 问题中删除 [javascript] 标记。即使在这种情况下,使用语言标签仍然是完全有效的(并且对关注标签的人很有用)。在不存在的地方添加框架标签是一个很好的改变,但删除 [javascript] 不是。

标签: javascript reactjs foreach jsx


【解决方案1】:

你是对的,forEach 不返回任何内容,使用 map 代替,它将返回一个 JSX 组件数组。

Map 也允许您访问密钥:resultsByGuid.map((item, key) =&gt; { })

编辑我很抱歉我急于求成,没有读到您正在使用Map 数据结构。 forEach 不会渲染任何东西,因为你需要返回值,你可以实现自己的 Array.map 像迭代器:

const mapIterator = (map, cb) => {
  const agg = [];
  for(let [key, value] of map) {
    agg.push(cb(value, key));
  }
  return agg;
};

<div className='gallery__items'>
  {mapIterator(resultsByGuid, (result, index) => {
    key++;
    return this.renderGalleryItem(result, key);
  })}
</div>

编辑 2 感谢@zerkms 指出对我来说应该很明显的事情:

<div className='gallery__items'>
  {Array.from(resultsByGuid.values()).map((result, index) => {
    key++;
    return this.renderGalleryItem(result, key);
  })}
</div>

【讨论】:

  • 你指的map是什么?
  • 但它确实有一个entries() 方法,您应该可以在for 循环的上下文中使用它...如果没有,您可以随时调用keys() 方法地图...
  • 确实有。 .values() 会更好。
  • Array.from(resultsByGuid.values()).map(...)[...resultsByGuid.values()].map(...)
  • 我错过了什么?每次您想对其执行任何类型的 map/reduce/filter 功能时,都必须将 Map 重组为数组,这似乎是非常低效的。规范没有完成吗?有什么简单的方法可以编写内联迭代器函数吗?
【解决方案2】:

对 danday74 使用数组解构的示例略有改进。带有选项的 ES6 地图:

<select>
    {[...options].map(([key, value]) => (
        <option key={key} value={key}>
            {value}
        </option>
    ))}
</select>;

【讨论】:

  • 这在 devtools 中对我有用,但是当我在我的 JSX 中尝试这个时,我得到“Uncaught TypeError: options.concat is not a function”,但是来自@Rob M 的{Array.from(options.entries()).map(([k, v]) =&gt; ([k, v])}。对我有用...可能缺少一些 babel-plugin,嗯...
【解决方案3】:

另一个选项,options 是一个 es6 Map() ..

<select>
  {
    [...options].map((entry) => {
      let key = entry[0]
      let value = entry[1]
      return <option key={ key } value={ key }>{ value }</option>
    })
  }
</select>

【讨论】:

  • 谢谢!这对我帮助很大。
【解决方案4】:

如果您在地图上调用.entries(),您将获得一个迭代器对象,该对象对于每个键/值对都包含一个数组,其结构为:[key, value],如提到的here

所以你可以这样做:

<div className='gallery__items'>
  {resultsByGuid.entries().map((result) => {
    return this.renderGalleryItem(result[1], result[0]);
  })}
</div>

我仍然想知道是否有更简单的解决方案。

【讨论】:

  • .entries() 返回一个迭代器,而不是一个数组!
  • 谢谢@hyperknot!我相应地更正了我的答案。
猜你喜欢
  • 1970-01-01
  • 2015-12-18
  • 2017-01-03
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
相关资源
最近更新 更多