我遇到的问题是我尝试使用数据数组来呈现<ul>
元素。在下面的代码中,console.log
工作正常,但列表项目没有出现。
var Main = React.createClass({
getInitialState: function(){
return {
data: dataRecent
}
},
render: function(){
return (
<div>
<ul>
{
this.state.data.map(function(item, i){
console.log('test');
<li>Test</li>
})
}
</ul>
</div>
)
}
});
ReactDOM.render(<Main />, document.getElementById('app'));
我做错了什么?请随意指出任何不是最佳做法。感谢。
答案 0 :(得分:44)
Gosha Arinich是对的,您应该返回<li>
元素。
但是,在这种情况下,你应该在浏览器控制台中得到令人讨厌的红色警告
数组或迭代器中的每个子节点都应该有一个唯一的“键”支柱。
所以,您需要在列表中添加“key”:
this.state.data.map(function(item, i){
console.log('test');
return <li key={i}>Test</li>
})
或删除console.log()
并使用es6 arrow functions做一个漂亮的oneliner:
this.state.data.map((item,i) => <li key={i}>Test</li>)
重要更新:
上面的答案是解决当前问题,但是在评论中提到Sergey:如果要进行一些过滤和排序,则使用取决于地图索引的键是BAD。在这种情况下,如果item.id
已经存在,请使用id
,或者只为其生成唯一ID。
答案 1 :(得分:5)
你没有回来。改为
this.state.data.map(function(item, i){
console.log('test');
return <li>Test</li>;
})
答案 2 :(得分:3)
您隐式返回undefined
。你需要返回元素。
this.state.data.map(function(item, i){
console.log('test');
return <li>Test</li>
})
答案 3 :(得分:3)
let durationBody = duration.map((item, i) => {
return (
<option key={i} value={item}>
{item}
</option>
);
});
答案 4 :(得分:0)
此解决方案的实现遇到了问题。
如果您要遍历自定义组件,并且希望共享状态,则该组件将不可用,因为.map()范围无法识别一般的state()范围。 我来到了这个解决方案:
`
class RootComponent extends Component() {
constructor(props) {
....
this.customFunction.bind(this);
this.state = {thisWorks: false}
this.that = this;
}
componentDidMount() {
....
}
render() {
let array = this.thatstate.map(() => {
<CustomComponent that={this.that} customFunction={this.customFunction}/>
});
}
customFunction() {
this.that.setState({thisWorks: true})
}
}
class CustomComponent extend Component {
render() {
return <Button onClick={() => {this.props.customFunction()}}
}
}
在没有这个的构造函数绑定中。
根组件内部对函数/方法的每次使用都应与this.that
答案 5 :(得分:0)
加上Dmitry的答案,如果您不想手动处理唯一的密钥ID,可以按照React documentation的建议使用React.Children.toArray
React.Children.toArray
将子级不透明数据结构返回为平面数组,并为每个子级分配了键。如果要在渲染方法中操纵子级的集合,特别是如果要在传递它之前重新排序或切片this.props.children,则很有用。
注意:
React.Children.toArray()
会在平整子级列表时更改键以保留嵌套数组的语义。也就是说,toArray在返回的数组中的每个键之前添加前缀,以便每个元素的键的作用域都限于包含它的输入数组。
<div>
<ul>
{
React.Children.toArray(
this.state.data.map((item, i) => <li>Test</li>)
)
}
</ul>
</div>
答案 6 :(得分:0)
德米特里·布林(Dmitry Brin)的回答对我有用,但有一个警告。就我而言,我需要在列表标记之间运行一个函数,该函数需要嵌套的JSX大括号。下面的示例JSX对我有用:
{this.props.data().map(function (object, i) { return <li>{JSON.stringify(object)}</li> })}
如果您不使用嵌套的JSX大括号,例如:
{this.props.data().map(function (object, i) { return <li>JSON.stringify(object)</li>})}
然后在HTML输出中获得“ JSON.stringify(object)”列表,这可能不是您想要的。
答案 7 :(得分:0)
使用无状态功能组件我们将不会使用this.state。像这样
{data1.map((item,key)=>
{ return
<tr key={key}>
<td>{item.heading}</td>
<td>{item.date}</td>
<td>{item.status}</td>
</tr>
})}
答案 8 :(得分:-2)
import React, { Component } from 'react';
class Result extends Component {
render() {
if(this.props.resultsfood.status=='found'){
var foodlist = this.props.resultsfood.items.map(name=>{
return (
<div className="row" key={name.id} >
<div className="list-group">
<a href="#" className="list-group-item list-group-item-action disabled">
<span className="badge badge-info"><h6> {name.item}</h6></span>
<span className="badge badge-danger"><h6> Rs.{name.price}/=</h6></span>
</a>
<a href="#" className="list-group-item list-group-item-action disabled">
<div className="alert alert-dismissible alert-secondary">
<strong>{name.description}</strong>
</div>
</a>
<div className="form-group">
<label className="col-form-label col-form-label-sm" htmlFor="inputSmall">Quantitiy</label>
<input className="form-control form-control-sm" placeholder="unit/kg" type="text" ref="qty"/>
<div> <button type="button" className="btn btn-success"
onClick={()=>{this.props.savelist(name.item,name.price);
this.props.pricelist(name.price);
this.props.quntylist(this.refs.qty.value);
}
}>ADD Cart</button>
</div>
<br/>
</div>
</div>
</div>
)
})
}
return (
<ul>
{foodlist}
</ul>
)
}
}
export default Result;