Làm cách nào để lặp và kết xuất các phần tử trong React.js mà không cần một mảng các đối tượng để ánh xạ?


145

Tôi đang cố gắng chuyển đổi một thành phần jQuery thành React.js và một trong những điều tôi gặp khó khăn là hiển thị n số phần tử dựa trên vòng lặp for.

Tôi hiểu điều này là không thể, hoặc được khuyến nghị và khi một mảng tồn tại trong mô hình thì nó hoàn toàn có ý nghĩa để sử dụng map. Điều đó tốt, nhưng khi bạn không có một mảng thì sao? Thay vào đó, bạn có giá trị số tương đương với một số phần tử nhất định để hiển thị, vậy bạn nên làm gì?

Dưới đây là ví dụ của tôi, tôi muốn tiền tố một phần tử với số lượng thẻ nhịp tùy ý dựa trên mức phân cấp của nó. Vì vậy, ở cấp 3, tôi muốn 3 thẻ span trước phần tử văn bản.

Trong javascript:

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

Tôi dường như không thể có được điều này, hoặc bất cứ điều gì tương tự để hoạt động trong thành phần JSX React.js. Thay vào đó tôi phải làm như sau, đầu tiên xây dựng một mảng tạm thời với độ dài chính xác và sau đó lặp lại mảng đó.

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"
    ...
  );
}

Chắc chắn đây không phải là cách tốt nhất, hay là cách duy nhất để đạt được điều này? Tôi đang thiếu gì?



bạn cũng có thể làm điều đó: jsfiddle.net/crl/69z2wepo/19804
caub

Câu trả lời:


241

Đã cập nhật: Kể từ khi Phản ứng> 0,16

Phương thức kết xuất không nhất thiết phải trả về một phần tử. Một mảng cũng có thể được trả về.

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

HOẶC LÀ

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

Tài liệu ở đây giải thích về trẻ em JSX


CŨ:

Bạn có thể sử dụng một vòng lặp thay thế

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>
);

Bạn cũng có thể sử dụng .map và es6 ưa thích

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

Ngoài ra, bạn phải bọc giá trị trả lại trong một container. Tôi đã sử dụng div trong ví dụ trên

Như các tài liệu nói ở đây

Hiện tại, trong kết xuất của một thành phần, bạn chỉ có thể trả về một nút; nếu bạn có một danh sách các div sẽ trả về, bạn phải bọc các thành phần của mình trong một div, span hoặc bất kỳ thành phần nào khác.


1
Điều đó làm việc, và nó đơn giản hơn nhiều cảm ơn. Có, tôi biết rằng bạn phải bọc giá trị trả về trong container, tôi đang làm điều đó đã bị thiếu trong ví dụ.
Jonathan Miles

2
thêm các khóa bên trong vòng lặp. chìa khóa rất quan trọng trong phản ứng.
Aamir Afridi

4
Tôi đã tìm kiếm tất cả các bạn trong cuộc sống của tôi
olleh

2
@ElgsQianChen Không thể. Nó phải được bọc bằng một số thẻ. Nếu {indents} trả về một phần tử dom duy nhất có nội dung bên trong nó, thì nó ổn
Dhiraj

2
Tôi không hiểu tại sao phương thức bản đồ được đề cập trong câu trả lời này, vì nó chỉ hoạt động cho các đối tượng Array, mà câu hỏi nêu rõ không phải là trường hợp.
flukyspore

47

Dưới đây là ví dụ chức năng hơn với một số tính năng 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;

1
Điều này trông giống như cách 'Phản ứng' nhất để làm điều đó. Truyền giá trị làm đạo cụ cho thành phần phụ khác. Cảm ơn!
Michael Giovanni Pumo

No rât hay! Hoàn hảo khi render của bạn () nặng html.
matthew

Để làm cho nó nhiều ES6 hơn, bạn có thể sử dụng import React from "react"export default Articles
jonlink

1
Câu trả lời này thậm chí không cố gắng trả lời câu hỏi. Câu hỏi rất rõ ràng, làm thế nào để chuyển đổi một for loopmảng (hoặc đối tượng) có thể ánh xạ để hiển thị n số mục trong thành phần React mà không cần một mảng các mục. Bạn giải pháp hoàn toàn bỏ qua thực tế đó và giả sử được thông qua một loạt các bài báo từ đạo cụ.
Jonathan Miles

17

Tôi đang sử dụng Object.keys(chars).map(...)để lặp trong kết xuất

// 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>
    );
}

Câu trả lời của bạn đã làm việc cho tôi, nhưng chỉ sau khi tôi thêm chars && ....bind(this)vào cuối chức năng của tôi. Tôi tò mò tại sao chỉ đơn thuần Object...(vân vân và vân vân) không hoạt động. Tôi tiếp tục không xác định.
m00saca

2
Điều này không trả lời câu hỏi, nó đặc biệt nói rằng không có một mảng các đối tượng để phân tích và giải thích rõ ràng nói rằng tôi muốn chuyển đổi một vòng lặp for thành ánh xạ để hiển thị trong thành phần React. Bạn thay thế mảng cho một đối tượng không giúp trả lời câu hỏi hoặc thêm bất kỳ giá trị nào khác.
Jonathan Miles

16

Array.from()mất một đối tượng lặp để chuyển đổi thành một mảng và một chức năng bản đồ tùy chọn. Bạn có thể tạo một đối tượng với một thuộc .lengthtính như sau:

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

Tôi chỉ tình cờ thấy câu hỏi của bạn sau khi nghe tuần này, vì vậy đó là cách nhanh nhất để áp dụng những gì tôi đã học! cú pháp.fm / show / 043 / từ
conradj

1
Chỉ cần những gì tôi cần để hiển thị X số phần tử, cảm ơn bạn!
Liran H

0

Tôi nghĩ rằng đây là cách dễ nhất để lặp lại trong phản ứng js

<ul>
    {yourarray.map((item)=><li>{item}</li>)}
</ul>

2
Điều này không trả lời câu hỏi, xin vui lòng đọc câu hỏi đầy đủ trước khi cố gắng trả lời.
Jonathan Miles

nó đã giúp tôi và tiết kiệm thời gian của tôi
Ajay Malhotra
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.