在尝试将父数据传递给子组件时,我不断碰壁。
我的观点:
<%= react_component 'Items', { data: @items } %>
我的Items
组件进行ajax调用,设置状态并呈现Item
。让key={this.props.id}
离开传递到映射函数的Item
实例,使得组件html呈现给页面。但是添加了密钥,我收到了一个控制台错误:Uncaught TypeError: Cannot read property 'id' of undefined
此处&#39;项目&#39;:
var Items = React.createClass({
loadItemsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
componentDidMount: function() {
this.loadItemsFromServer();
},
render: function() {
var itemNodes = this.props.data.map(function() {
return (
<Item key={this.props.id} />
);
});
return (
<div className="ui four column doubling stackable grid">
{itemNodes}
</div>
);
}
});
我的item.js.jsx组件只格式化每个Item
:
var Item = React.createClass({
render: function() {
return (
<div className="item-card">
<div className="image">
</div>
<div className="description">
<div className="artist">{this.props.artist}</div>
</div>
</div>
);
}
});
React dev工具扩展显示了Items中的props和state数据。然而,孩子们都是空的。
我了解this,但我设置了this.props.id
的密钥。我不确定我错过了什么?
答案 0 :(得分:1)
我在Items
组件
this.props.data
,而实际上this.state.data
是使用ajax请求更新的this.state.data
。您需要呈现props
,但需要从var Item = React.createClass({
render: function() {
return (
<div className="item-card">
<div className="image">
</div>
<div className="description">
<div className="artist">{this.props.artist}</div>
</div>
</div>
);
}
});
var Items = React.createClass({
getInitialState: function() {
return {
// for initial state use the array passed as props,
// or empty array if not passed
data: this.props.data || []
};
},
loadItemsFromServer: function() {
var data = [{
id: 1,
artist: 'abc'
}, {
id: 2,
artist: 'def'
}]
this.setState({
data: data
});
},
componentDidMount: function() {
this.loadItemsFromServer();
},
render: function() {
// use this.state.data not this.props.data,
// since you are updating the state with the result of the ajax request,
// you're not updating the props
var itemNodes = this.state.data.map(function(item) {
// the map iterator function takes an item as a parameter,
// which is the current element of the array (this.state.data),
// use (item) to access properties, not (this)
return (
// use key as item id, and pass all the item properties
// to the Item component with ES6 object spread syntax
<Item key={item.id} {...item} />
);
});
return (
<div className="ui four column doubling stackable grid">
{itemNodes}
</div>
);
}
});
更新的代码应如下所示
<form action="/picUploader.jsp" method="POST" ENCTYPE="multipart/form-data">
<input type="hidden" name="INDIVIDUALID" value="001">
<input type="hidden" name="SYSTEMID" value="J">
<select name="PICTYPEID" size="1">
<option value="-" ></option>
<option value="1" >FRONT</option>
</select>
<input type="file" name="PICTURE">
</form>
答案 1 :(得分:0)
您的实施存在一些问题。
首先,您需要决定:是否要将@items从视图中传递给Items组件?或者你想异步加载它们? 因为现在我得到你想要做的两个印象......
渲染从视图传递的项目
如果要将视图中的项目传递给组件,请确保它是正确的json。您可能需要在其上调用'as_json'。
<%= react_component 'Items', { data: @items.as_json } %>
然后,在您的Component中,映射项目以呈现<Item />
组件。关于你的密钥,这是第二个问题。您需要将item变量定义为map函数的回调函数,并从中读取id:
var itemNodes = this.props.data.map(function(item) {
return (
<Item key={item.id} artist={item.artist} />
);
});
注意,我还将作者添加为道具,因为您在<Item />
组件中使用它。
您可以删除componentDidMount
和loadItemsFromServer
个功能,因为您没有使用它们。
异步加载项
如果您要异步加载项目,就像您在loadItemsFromServer
函数中尝试的那样,首先,从您的视图中传递网址并删除{data:@items}部分,因为您将从您的组件加载项目,如:
<%= react_component 'Items', { url: items_path(format: :json) } %>
如果要渲染异步提取的项目,请使用:
var itemNodes = this.state.data.map(function(item) {
return (
<Item key={item.id} artist={item.artist} />
);loadItemsFromServer
});
注意我已将this.props.map
更改为this.state.map
您现在可以使用componentDidMount和loadItemsFromServer函数加载数据并将其保存到状态。