所以我有这个组件
var LineItemRowsWrapper = React.createClass({
current_lineitem_count: 0,
getAjaxData: function(){
var lineitem_data = [];
for(var i = 0; i < this.current_lineitem_count; i++){
var data = this.refs['lineitem_'+i].getAjaxData();
lineitem_data.push(data)
}
return lineitem_data;
},
getLineitems: function(){
var self = this;
var lineitem_components = [];
this.current_lineitem_count = 0;
if(this.props.shoot){
var preview = this.props.preview;
var lineitems = this.props.shoot.get_lineitems();
lineitem_components = lineitems.map(function (item, index) {
var ref_str = 'lineitem_'+self.current_lineitem_count;
self.current_lineitem_count++;
return (
<LineItemRow item={item} key={index} ref={ref_str} preview={preview} onChange={self.props.onChange} />
)
});
}
return lineitem_components;
},
render: function() {
var lineitems = this.getLineitems();
return (
<div>
{lineitems}
</div>
)
}
})
第一次提供lineitems,refs就像预期的那样工作。但是如果我在this.props.shoot中添加一个lineitem,则该组件的refs对象不会改变。
例如,假设我有一个包含3个lineitems的数组
[i1,i2,i3]
this.refs将是
{lineitem_0:{}, lineitem_1:{}, lineitem_2:{}}
当我将我的lineitem数组更新为
时 [i1,i2,i3,i4]
this.refs不会改变,它仍然是
{lineitem_0:{}, lineitem_1:{}, lineitem_2:{}}
为什么refs对象不能在渲染之间更新? LineItemRow组件正确更新,所以我知道它在前面没有错。任何见解都会非常感激!
____ Edit____(要求为上下文添加更多代码)
var DocumentContent = React.createClass({
contextTypes: {
router: React.PropTypes.func.isRequired
},
getParams: function(){
return this.context.router.getCurrentParams()
},
getInitialState: function() {
return {
shoot: ShootStore.get_shoot(this.getParams().shoot_id),
}
},
componentWillMount: function() {
ShootStore.bind( 'change', this.onStoreUpdate );
},
componentWillUnmount: function() {
ShootStore.unbind( 'change', this.onStoreUpdate );
},
onStoreUpdate: function(){
this.setState(this.getInitialState());
},
addLineItem: function() {
ShootActions.create_lineitem(this.state.shoot.id);
},
update_shoot_timeout: null,
update_shoot:function(){
var self = this;
window.clearTimeout(this.update_shoot_timeout)
this.update_shoot_timeout = window.setTimeout(function(){
var lineitem_data = self.refs.lineitems.getAjaxData()
if(self.props.shoot){
ShootActions.update_shoot(self.state.shoot.id, lineitem_data )
}
}, 500)
},
render: function() {
var shoot = this.state.shoot;
return (
<div className='document__content'>
<div className='row'>
<div className='document__expenses'>
<h3 className='lineitem__title'> Expenses </h3>
<LineItemRowsWrapper shoot={shoot} onChange={this.update_shoot} ref='lineitems'/>
</div>
<button onClick={this.addLineItem} className="btn-small btn-positive">
+ Add Expense
</button>
</div>
);
}
})
答案 0 :(得分:6)
在&#34;注意&#34;部分下在refs https://facebook.github.io/react/docs/more-about-refs.html
的反应文档中&#34;永远不要访问任何组件的渲染方法中的引用 - 或者同时访问 任何组件的渲染方法甚至可以在调用中的任何位置运行 堆栈&#34;
这正是你正在做的事情。
相反,您应该在this.state
中存储有关组件的状态,或者在this.props
答案 1 :(得分:0)
删除所有引用和迭代以读取数据。
应该调用一直传递给LineItem组件的onchange处理程序,并仅传递更改的数据。 (单个LineItem数据)
然后在具有状态处理(DocumentContent)的组件处回来。
创建一个动作ShootActions.updateLineItem(),用于更新商店中的相关订单项,然后发出更改并再次呈现所有内容。