如何在没有要映射的对象数组的情况下循环和渲染 React.js 中的元素?

IT技术 javascript jquery reactjs react-jsx
2021-01-25 14:19:43

我正在尝试将 jQuery 组件转换为 React.js,我遇到的困难之一是基于 for 循环渲染 n 个元素。

我知道这是不可能的,或推荐的,并且模型中存在数组的地方使用map. 那很好,但是当您没有数组时怎么办?相反,您有一个数值,它等于要呈现的给定数量的元素,那么您应该怎么做?

这是我的示例,我想根据元素的层次级别为元素添加任意数量的跨度标记作为前缀。所以在第 3 级,我希望在文本元素之前有 3 个 span 标签。

在 JavaScript 中:

for (var i = 0; i < level; i++) {
    $el.append('<span class="indent"></span>');
}
$el.append('Some text value');

我似乎无法得到这个,或者任何类似于在 JSX React.js 组件中工作的东西。相反,我必须执行以下操作,首先构建一个正确长度的临时数组,然后循环该数组。

react.js

render: function() {
  var tmp = [];
  for (var i = 0; i < this.props.level; i++) {
    tmp.push(i);
  }
  var indents = tmp.map(function (i) {
    return (
      <span className='indent'></span>
    );
  });

  return (
    ...
    {indents}
    "Some text value"
    ...
  );
}

这肯定不是最好的,或者是实现这一目标的唯一方法?我错过了什么?

6个回答

更新:从 React > 0.16

Render 方法不一定必须返回单个元素。也可以返回一个数组。

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return indents;

或者

return this.props.level.map((item, index) => (
    <span className="indent" key={index}>
        {index}
    </span>
));

此处的文档解释了 JSX 儿童


老的:

您可以使用一个循环代替

var indents = [];
for (var i = 0; i < this.props.level; i++) {
  indents.push(<span className='indent' key={i}></span>);
}
return (
   <div>
    {indents}
    "Some text value"
   </div>
);

您还可以使用.map和花式 es6

return (
   <div>
    {this.props.level.map((item, index) => (
       <span className='indent' key={index} />
    ))}
    "Some text value"
   </div>
);

此外,您必须将返回值包装在容器中。我在上面的例子中使用了 div

正如文档在这里所说

目前,在一个组件的渲染中,你只能返回一个节点;例如,如果您有一个要返回的 div 列表,则必须将组件包装在 div、span 或任何其他组件中。

我一生都在寻找你
2021-03-19 14:19:43
我不明白为什么在这个答案中提到了 map 方法,因为它只适用于 Array 对象,问题明确指出并非如此。
2021-03-25 14:19:43
那行得通,而且简单多了,谢谢。是的,我知道您必须将返回值包装在容器中,我已经这样做了,只是示例中缺少它。
2021-04-01 14:19:43
在循环内添加键。键在反应中很重要。
2021-04-06 14:19:43
@ElgsQianChen 不可能。它必须用一些标签包裹。如果 {indents} 返回一个包含内容的单个 dom 元素,那么它可以
2021-04-06 14:19:43

这是具有一些 ES6 特性的更多功能示例:

'use strict';

const React = require('react');

function renderArticles(articles) {
    if (articles.length > 0) {      
        return articles.map((article, index) => (
            <Article key={index} article={article} />
        ));
    }
    else return [];
}

const Article = ({article}) => {
    return ( 
        <article key={article.id}>
            <a href={article.link}>{article.title}</a>
            <p>{article.description}</p>
        </article>
    );
};

const Articles = React.createClass({
    render() {
        const articles = renderArticles(this.props.articles);

        return (
            <section>
                { articles }
            </section>
        );
    }
});

module.exports = Articles;
这是一个伟大的!非常适合当您的 render() 是 html 重的时候。
2021-03-20 14:19:43
为了使它更像 ES6,你可以使用import React from "react"export default Articles
2021-04-03 14:19:43
这个答案甚至没有试图回答这个问题。问题很清楚,如何将 a 转换为for loop可映射的数组(或对象),以便在没有项目数组的情况下在 React 组件中呈现 n 个项目。您的解决方案完全忽略了这一事实,并假设从 props 传递了一系列文章。
2021-04-04 14:19:43
这看起来是最“反应”的方式来做到这一点。将值作为道具传递给另一个子组件。谢谢!
2021-04-08 14:19:43

Array.from()接受一个可迭代对象转换为一个数组和一个可选的 map 函数。您可以创建一个具有.length属性的对象,如下所示:

return Array.from({length: this.props.level}, (item, index) => 
  <span className="indent" key={index}></span>
);
正是我渲染 X 个元素所需要的,谢谢!
2021-03-17 14:19:43

我正在使用Object.keys(chars).map(...)循环渲染

// chars = {a:true, b:false, ..., z:false}

render() {
    return (
       <div>
        {chars && Object.keys(chars).map(function(char, idx) {
            return <span key={idx}>{char}</span>;
        }.bind(this))}
        "Some text value"
       </div>
    );
}
你的回答对我有用,但只有在我添加chars && ....bind(this)结束我的功能之后。我很好奇为什么仅仅Object...(等等)不起作用。我一直未定义。
2021-03-16 14:19:43
这并没有回答问题,它特别说明没有要解析的对象数组,并且解释明确说明我想将 for 循环转换为映射以在 React 组件中呈现。您将数组替换为无助于回答问题的对象,或添加任何其他值。
2021-04-11 14:19:43

map如果您有能力创建临时数组,您仍然可以使用

{
    new Array(this.props.level).fill(0).map((_, index) => (
        <span className='indent' key={index}></span>
    ))
}

这工作,因为new Array(n).fill(x)创建大小的数组n填充x,然后可以帮助map

数组填充