Bagaimana cara mengulang dan merender elemen dalam React.js tanpa array objek untuk dipetakan?

146

Saya mencoba untuk mengkonversi komponen jQuery ke React.js dan salah satu hal yang saya mengalami kesulitan dengan rendering n sejumlah elemen berdasarkan for for loop.

Saya mengerti ini tidak mungkin, atau direkomendasikan dan bahwa di mana ada array dalam model itu masuk akal untuk digunakan map. Tidak apa-apa, tetapi bagaimana dengan ketika Anda tidak memiliki array? Alih-alih Anda memiliki nilai numerik yang setara dengan sejumlah elemen yang diberikan untuk dirender, lalu apa yang harus Anda lakukan?

Inilah contoh saya, saya ingin awalan elemen dengan jumlah tag rentang yang sewenang-wenang berdasarkan tingkat hierarkisnya. Jadi pada level 3, saya ingin 3 tag rentang sebelum elemen teks.

Dalam javascript:

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

Saya sepertinya tidak bisa mendapatkan ini, atau apa pun yang serupa dengan bekerja di komponen JSX React.js. Alih-alih saya harus melakukan yang berikut, pertama membangun array temp dengan panjang yang benar dan kemudian mengulang array.

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

Tentunya ini bukan yang terbaik, atau satu-satunya cara untuk mencapai ini? Apa yang saya lewatkan?

Jonathan Miles
sumber
Anda juga bisa melakukannya: jsfiddle.net/crl/69z2wepo/19804
caub

Jawaban:

242

Diperbarui: Pada Bereaksi> 0,16

Metode rendering tidak harus mengembalikan elemen tunggal. Array juga dapat dikembalikan.

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

ATAU

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

Documents di sini menjelaskan tentang anak-anak BEJ


TUA:

Anda bisa menggunakan satu loop sebagai gantinya

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

Anda juga dapat menggunakan .map dan fancy es6

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

Juga, Anda harus membungkus nilai pengembalian dalam wadah. Saya menggunakan div dalam contoh di atas

Seperti yang dikatakan para dokter di sini

Saat ini, dalam render komponen, Anda hanya dapat mengembalikan satu simpul; jika Anda memiliki, katakanlah, daftar div untuk dikembalikan, Anda harus membungkus komponen Anda dalam div, rentang atau komponen lainnya.

Dhiraj
sumber
1
Itu berhasil, dan terima kasih lebih sederhana. Ya saya sadar bahwa Anda harus membungkus nilai kembali dalam wadah, saya sudah melakukan itu baru saja hilang dari contoh.
Jonathan Miles
2
tambahkan kunci di dalam loop. kunci penting dalam bereaksi.
Aamir Afridi
4
Aku sudah mencarimu seumur hidupku
olleh
2
@ ElgsQianChen Ini tidak mungkin. Itu harus dibungkus dengan beberapa tag. Jika {indents} mengembalikan elemen dom tunggal dengan konten di dalamnya, maka ok
Dhiraj
2
Saya tidak mengerti mengapa metode peta disebutkan dalam jawaban ini, karena hanya berfungsi untuk objek Array, yang pertanyaannya jelas nyatakan tidak demikian.
flukyspore
47

Berikut adalah contoh yang lebih fungsional dengan beberapa fitur 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;
Dmytro Medvid
sumber
1
Ini sepertinya cara yang paling 'Reacty' untuk melakukannya. Berikan nilai sebagai penyangga ke sub komponen lainnya. Terima kasih!
Michael Giovanni Pumo
Ini hebat! Sempurna untuk saat render Anda () berat html.
matthew
Untuk membuatnya lebih ES6, Anda dapat menggunakan import React from "react"danexport default Articles
jonlink
1
Jawaban ini bahkan tidak berusaha menjawab pertanyaan itu. Pertanyaannya jelas, bagaimana mengonversi sebuah for looparray (atau objek) map'able untuk merender n jumlah item dalam komponen Bereaksi tanpa memiliki array item. Solusi Anda benar-benar mengabaikan fakta itu dan mengasumsikan telah melewati sejumlah artikel dari alat peraga.
Jonathan Miles
17

Saya menggunakan Object.keys(chars).map(...)untuk loop dalam render

// 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>
    );
}
Mathdoy
sumber
Jawaban Anda berhasil untuk saya, tetapi hanya setelah saya menambahkan chars && ...dan .bind(this)pada akhir fungsi saya. Saya ingin tahu mengapa hanya Object...(seterusnya dan seterusnya) tidak berhasil. Saya terus terdefinisi.
m00saca
2
Ini tidak menjawab pertanyaan, ia secara khusus mengatakan tanpa array objek untuk diuraikan dan penjelasan secara eksplisit mengatakan bahwa saya ingin mengonversi perulangan for untuk dipetakan untuk dirender dalam komponen Bereaksi. Anda mengganti array untuk objek yang tidak membantu menjawab pertanyaan, atau menambahkan nilai lebih lanjut.
Jonathan Miles
16

Array.from()mengambil objek yang dapat diubah untuk dikonversi ke array dan fungsi peta opsional. Anda bisa membuat objek dengan .lengthproperti sebagai berikut:

return Array.from({length: this.props.level}, (item, index) => 
  <span className="indent" key={index}></span>
);
conradj
sumber
Saya kebetulan melihat pertanyaan Anda setelah mendengarkan minggu lalu, jadi itu cara tercepat untuk menerapkan apa yang saya pelajari! syntax.fm/show/043/…
conradj
1
Apa yang saya butuhkan untuk merender sejumlah elemen X, terima kasih!
Liran H
0

Saya pikir ini adalah cara termudah untuk loop dalam bereaksi js

<ul>
    {yourarray.map((item)=><li>{item}</li>)}
</ul>
Nasar uddin
sumber
2
Ini tidak menjawab pertanyaan, harap baca pertanyaannya sepenuhnya sebelum mencoba menjawab.
Jonathan Miles
itu membantu saya dan menghemat waktu saya.
Ajay Malhotra