Kết xuất các thành phần React từ Mảng đối tượng


98

Tôi có một số dữ liệu được gọi là các trạm là một mảng chứa các đối tượng.

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

Tôi muốn hiển thị một thành phần ui cho mỗi vị trí mảng. Cho đến nay tôi có thể viết

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

Và sau đó kết xuất

render(){
 return (
   {stationsArr}
 )
}

Vấn đề là tôi đang in tất cả dữ liệu ra. Thay vào đó, tôi muốn chỉ hiển thị một khóa như thế {this.data.call}nhưng không in ra gì.

Làm cách nào để tôi có thể lặp qua dữ liệu này và trả về một phần tử giao diện người dùng mới cho mỗi vị trí của mảng?


Tôi có thể sai nhưng tôi nghĩ bạn cần sử dụng stationsArrthay vì stationsbên trong renderhàm.
Tahir Ahmed

Câu trả lời:


151

Bạn có thể ánh xạ danh sách các trạm tới ReactElements.

Với React> = 16, có thể trả về nhiều phần tử từ cùng một thành phần mà không cần thêm một trình bao bọc phần tử html. Kể từ ngày 16.2, có một cú pháp mới <> để tạo các phân mảnh. Nếu điều này không hoạt động hoặc không được IDE của bạn hỗ trợ, bạn có thể sử dụng <React.Fragment>thay thế. Trong khoảng từ 16.0 đến 16.2, bạn có thể sử dụng một polyfill rất đơn giản cho các đoạn.

Hãy thử những điều sau đây

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

Đừng quên keythuộc tính!

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


@thatgibbyguy: À vâng! đó có thể là câu trả lời đúng. Cần có một lớp bọc xung quanh các thành phần con của bạn. renderHàm của bạn phải trả về một phần tử duy nhất.
Tahir Ahmed

Lý do đề xuất thuộc tính khóa cho mỗi phần tử trạm là gì? Điều tôi đang hỏi là, điều đó sẽ thay đổi gì nếu bây giờ không cần thiết?
thatgibbyguy

4
@thatgibbyguy trong trường hợp này không mang lại nhiều lợi thế. Trong các ví dụ nâng cao hơn, nó cho phép có hiệu suất hiển thị tốt hơn vì React có thể dễ dàng biết liệu một nút hiện có đã được chuyển đến một vị trí khác trong mảng trạm hay chưa, do đó tránh phá hủy và tạo lại một nút dom hiện có (và cũng giữ cho nút dom được gắn kết) . Nó nằm trong tài liệu phản ứng: facebook.github.io/react/docs/reconcoring.html#keys
Sebastien Lorber.

Hơi lạc đề nhưng tôi không chắc làm thế nào để xây dựng một truy vấn để hỏi điều này. Khi sử dụng cú pháp ES6 trong ví dụ của bạn ở trên, làm thế nào để chuyển chỉ mục từ bản đồ? IOW, làm thế nào tôi có thể tìm ra nếu tôi đang ở trong nút cuối cùng của mảng? Tôi đã thử gói trong parens và điều đó có vẻ không suôn sẻ.
Lane Goolsby

@ElHombre stations.map((station,index) => { })hoạt động tốt đối với tôi
Sebastien Lorber

45

Tôi có một câu trả lời có thể hơi khó hiểu cho những người mới như tôi. Bạn chỉ có thể sử dụng maptrong phương thức kết xuất các thành phần.

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

11
Điều này cần một ứng dụng keyhỗ trợ reactjs.org/docs/lists-and-keys.html#keys
David Barratt,

1
Đôi khi điều này hữu ích hơn nhiều. :)
ferit

6

this.data có lẽ chứa tất cả dữ liệu, vì vậy bạn cần phải làm như sau:

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

Hoặc bạn có thể sử dụng mapvà các hàm mũi tên nếu bạn đang sử dụng ES6:

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

2
Điều này sẽ không hoạt động trong Phiên bản React hiện tại, bạn không thể trả về một mảng.
Aftab Naveed

@AftabNaveed cảm ơn Tôi đã cập nhật nó, kết xuất sẽ trả về một phần tử nhưng nó hợp lệ để có một mảng các phần tử bên trong đó
Dominic

Như @AftabNaveed đã nói, nếu phiên bản phản ứng <16, bạn sẽ cần sử dụng ở trên, nếu không bạn có thể chỉ return stations;( codepen.io/pawelgrzybek/pen/WZEKWj )
Chicken Soup vào

1

Có một số cách có thể được sử dụng.

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

Giải pháp 1

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

Giải pháp 2

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

Chỉnh sửa kind-antonelli-z8372

Tất nhiên cũng có những cách khác.

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.