从对象数组渲染React组件


98

我有一些称为站的数据,它是一个包含对象的数组。

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而不是。stationsrender
塔希尔·艾哈迈德

Answers:


151

您可以将工作站列表映射到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函数必须返回一个元素。
塔希尔·艾哈迈德

为每个站点元素建议关键属性的原因是什么?我要问的是,如果现在不需要它会发生什么变化?
thatgibbyguy 2015年

4
@thatgibbyguy在这种情况下并没有带来太多优势。在更高级的示例中,它允许具有更好的渲染性能,因为React可以轻松知道现有节点是否已移动到站阵列中的另一个位置,从而避免破坏和重建现有dom节点(并保持dom节点安装) 。它在反应文档中:facebook.github.io/react/docs/reconciliation.html#keys
塞巴斯蒂安·洛伯

稍微偏离主题,但是我不确定如何构造查询来询问这个问题。在上面的示例中使用ES6语法时,如何从地图中传递索引?IOW,如何确定我是否在阵列的最后一个节点中?我尝试用包裹纸包裹,但效果似乎不太理想。
巷古尔斯比

@ElHombre stations.map((station,index) => { })对我来说效果很好
Sebastien Lorber


6

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版本中不起作用,您不能返回数组。
Aftab Naveed

@AftabNaveed,谢谢,我已经对其进行了更新,render应该返回一个元素,但是在其中包含一个元素数组是有效的
Dominic

作为@AftabNaveed说,如果反应版本<16,则需要使用上面,否则你可以return stations;codepen.io/pawelgrzybek/pen/WZEKWj
心灵鸡汤

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

当然,还有其他方法可用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.