การแสดงผลส่วนประกอบการตอบสนองจาก Array of Objects


106

ฉันมีข้อมูลบางอย่างที่เรียกว่าสถานีซึ่งเป็นอาร์เรย์ที่มีวัตถุ

stations : [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
]

ฉันต้องการแสดงองค์ประกอบ ui สำหรับตำแหน่งอาร์เรย์แต่ละตำแหน่ง จนถึงตอนนี้ฉันสามารถเขียนได้

 var stationsArr = []
 for (var i = 0; i < this.data.stations.length; i++) {
     stationsArr.push(
         <div className="station">
             {this.data}
         </div>
     )
 }

แล้วแสดงผล

render(){
 return (
   {stationsArr}
 )
}

ปัญหาคือฉันกำลังพิมพ์ข้อมูลทั้งหมดออกมา ฉันต้องการเพียงแค่แสดงคีย์ที่เหมือน{this.data.call}แต่ไม่ได้พิมพ์อะไรเลย

ฉันจะวนรอบข้อมูลนี้และส่งคืนองค์ประกอบ UI ใหม่สำหรับแต่ละตำแหน่งของอาร์เรย์ได้อย่างไร


ฉันอาจจะผิด แต่ฉันคิดว่าคุณต้องใช้stationsArrแทนstationsภายในrenderฟังก์ชัน
Tahir Ahmed

คำตอบ:


156

คุณสามารถแมปรายชื่อสถานีกับ ReactElements

ด้วย React> = 16 คุณสามารถส่งคืนองค์ประกอบหลายรายการจากองค์ประกอบเดียวกันได้โดยไม่ต้องใช้กระดาษห่อองค์ประกอบ html เพิ่มเติม ตั้งแต่ 16.2 เป็นต้นมามีไวยากรณ์ใหม่ <>เพื่อสร้างส่วนย่อย หากไม่ได้ผลหรือ IDE ของคุณไม่รองรับคุณสามารถใช้<React.Fragment>แทนได้ ระหว่าง 16.0 และ 16.2, คุณสามารถใช้ง่ายมากpolyfillสำหรับชิ้นส่วน

ลองทำดังต่อไปนี้

// Modern syntax >= React 16.2.0
const Test = ({stations}) => (
  <>
    {stations.map(station => (
      <div className="station" key={station.call}>{station.call}</div>
    ))}
  </>
); 

// Modern syntax < React 16.2.0
// You need to wrap in an extra element like div here

const Test = ({stations}) => (
  <div>
    {stations.map(station => (
      <div className="station" key={station.call}>{station.call}</div>
    ))}
  </div>
); 

// old syntax
var Test = React.createClass({
    render: function() {
        var stationComponents = this.props.stations.map(function(station) {
            return <div className="station" key={station.call}>{station.call}</div>;
        });
        return <div>{stationComponents}</div>;
    }
});

var stations = [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
]; 

ReactDOM.render(
  <div>
    <Test stations={stations} />
  </div>,
  document.getElementById('container')
);

อย่าลืมkeyแอตทริบิวต์!

https://jsfiddle.net/69z2wepo/14377/


@thatgibbyguy: โอ้ใช่! นั่นอาจเป็นคำตอบที่ถูกต้อง จำเป็นต้องมีการห่อส่วนประกอบลูกของคุณ renderฟังก์ชันของคุณต้องส่งคืนองค์ประกอบเดียว
Tahir Ahmed

อะไรคือเหตุผลในการแนะนำแอตทริบิวต์หลักสำหรับองค์ประกอบสถานีแต่ละรายการ สิ่งที่ฉันถามคืออะไรจะเปลี่ยนไปถ้ายังไม่ต้องการตอนนี้?
thatgibbyguy

4
@thatgibbyguy ในกรณีนี้จะไม่ก่อให้เกิดประโยชน์มากนัก ในตัวอย่างขั้นสูงจะอนุญาตให้มีการแสดงผลที่ดีขึ้นเนื่องจาก React สามารถทราบได้อย่างง่ายดายว่าโหนดที่มีอยู่ถูกย้ายไปที่อื่นในอาร์เรย์สถานีดังนั้นจึงหลีกเลี่ยงการทำลายและสร้างโหนดโหนดที่มีอยู่ใหม่ (และยังคงติดตั้งโหนดโดมไว้) . อยู่ในเอกสารตอบกลับ: facebook.github.io/react/docs/reconciliation.html#keys
Sebastien Lorber

นอกหัวข้อเล็กน้อย แต่ฉันไม่แน่ใจว่าจะสร้างแบบสอบถามเพื่อถามสิ่งนี้อย่างไร เมื่อใช้ไวยากรณ์ ES6 ในตัวอย่างด้านบนเราจะส่งดัชนีจากแผนที่ไปอย่างไร IOW ฉันจะทราบได้อย่างไรว่าฉันอยู่ในโหนดสุดท้ายของอาร์เรย์ ฉันลองห่อใน parens และดูเหมือนจะไม่เป็นไปด้วยดี
Lane Goolsby

@ElHombre stations.map((station,index) => { })ทำงานได้ดีสำหรับฉัน
Sebastien Lorber

50

ฉันมีคำตอบที่อาจจะสับสนไม่น้อยสำหรับมือใหม่อย่างตัวฉันเอง คุณสามารถใช้mapภายในวิธีการแสดงผลคอมโพเนนต์

render () {
   return (
       <div>
           {stations.map(station => <div key={station}> {station} </div>)} 
       </div>
   );
}

11
สิ่งนี้ต้องการkeyprop reactjs.org/docs/lists-and-keys.html#keys
David Barratt

2
บางครั้งสิ่งนี้มีประโยชน์มากกว่านั้นมาก :)
ferit

7

this.data น่าจะมีข้อมูลทั้งหมดดังนั้นคุณจะต้องทำสิ่งนี้:

var stations = [];
var stationData = this.data.stations;

for (var i = 0; i < stationData.length; i++) {
    stations.push(
        <div key={stationData[i].call} className="station">
            Call: {stationData[i].call}, Freq: {stationData[i].frequency}
        </div>
    )
}

render() {
  return (
    <div className="stations">{stations}</div>
  )
}

หรือคุณสามารถใช้mapและฟังก์ชั่นลูกศรหากคุณใช้ ES6:

const stations = this.data.stations.map(station =>
    <div key={station.call} className="station">
      Call: {station.call}, Freq: {station.frequency}
    </div>
);

2
สิ่งนี้จะใช้ไม่ได้ใน React Version ปัจจุบันคุณไม่สามารถส่งคืนอาร์เรย์ได้
Aftab Naveed

@AftabNaveed ขอบคุณที่ฉันอัปเดตแล้วการเรนเดอร์ควรส่งคืนองค์ประกอบหนึ่ง แต่มันถูกต้องที่จะมีอาร์เรย์ขององค์ประกอบภายในนั้น
Dominic

ดังที่ @AftabNaveed กล่าวว่าหากตอบสนองเวอร์ชัน <16 คุณจะต้องใช้ด้านบนมิฉะนั้นคุณสามารถทำได้return stations;( codepen.io/pawelgrzybek/pen/WZEKWj )
Chicken Suop

1

มีสองวิธีที่สามารถใช้ได้

const stations = [
  {call:'station one',frequency:'000'},
  {call:'station two',frequency:'001'}
];
const callList = stations.map(({call}) => call)

แนวทางแก้ไข 1

<p>{callList.join(', ')}</p>

โซลูชันที่ 2

<ol>    
  { callList && callList.map(item => <li>{item}</li>) }
</ol>

แก้ไข kind-antonelli-z8372

แน่นอนว่ายังมีวิธีอื่น ๆ


0

นี่เป็นวิธีที่ง่ายที่สุดในการบรรลุสิ่งที่คุณกำลังมองหา

ในการใช้mapฟังก์ชันนี้ในอินสแตนซ์นี้เราจะต้องส่งcurrentValueพารามิเตอร์ (จำเป็นเสมอ) และพารามิเตอร์index(ทางเลือก) ในตัวอย่างด้านล่างstationเป็นของเราcurrentValueและเป็นของเราxindex

stationแทนค่าปัจจุบันของวัตถุภายในอาร์เรย์เมื่อมีการทำซ้ำ xเพิ่มขึ้นโดยอัตโนมัติ เพิ่มขึ้นทีละครั้งทุกครั้งที่แมปวัตถุใหม่

render () {
    return (
        <div>
            {stations.map((station, x) => (
                <div key={x}> {station} </div>
            ))}
        </div>
    );
}

สิ่งที่ Thomas Valadez ตอบในขณะที่ได้ให้วิธีการที่ดีที่สุด / ง่ายที่สุดในการแสดงผลองค์ประกอบจากอาร์เรย์ของวัตถุ แต่ก็ล้มเหลวในการระบุวิธีที่คุณจะกำหนดคีย์ในระหว่างกระบวนการนี้อย่างถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.