[英]Child component props not reflecting state change from parent
The part of my app in question is utilizing 4 components, 1 parent and 3 children. 我的应用程序中涉及的部分是利用4个组件,即1个父级和3个孩子。 As expected, the parent component handles all state and passes values to child components via props.
如预期的那样,父组件处理所有状态并将值通过prop传递给子组件。
The parent component contains methods for updating state changes, also passed down via props. 父组件包含用于更新状态更改的方法,这些方法也通过props传递。 The child components do not have state other than component methods, they use only props for visual data.
子组件除组件方法外没有其他状态,它们仅将道具用于可视数据。
The problem I'm having is that when I call the method to update parent state, the parent state is updated successfully (verified via the console), however the child component, which reflects this state via its props, doesn't render the state change visually. 我遇到的问题是,当我调用更新父状态的方法时,父状态已成功更新(通过控制台进行了验证),但是通过其道具反映此状态的子组件未呈现该状态视觉上改变。
The code is below which I'll do my best to explain: 下面的代码将尽力解释:
Parent component update state method: 父组件更新状态方法:
handleUpvoteState(blurtIndex) {
let blurts = [...this.state.followingBlurts],
updatedBlurt = {...blurts[blurtIndex]};
updatedBlurt.vote++;
blurts[blurtIndex] = updatedBlurt;
this.setState({
followingBlurts: blurts
});
console.log(this.state.followingBlurts[blurtIndex].vote); // State change reflected.
}
Parent component passing state to child props: 父组件将状态传递给子道具:
<LazyBlurtsPanel
appendDate={this.state.appendDate}
random={this.state.randomize}
blurts={this.state.followingBlurts}
handleLazyState={this.handleLazyState}
handleUpvoteState={this.handleUpvoteState}
lazyElement='lzyfollowing'
apiMethod={this.state.apiMethod}
currentUser={false}
/>
The lazy panel component (above) then sends data to footer child via props: 惰性面板组件(上面)然后通过props将数据发送到footer child:
<BlurtFooter
voteCount={this.props.blurts[i].vote}
currentUser={this.props.currentUser}
blurtId={this.props.blurts[i]._id}
blurtIndex={i}
handleUpvoteState={this.props.handleUpvoteState}
/>
When I call 当我打电话
this.props.handleUpvoteState(index)
in my child footer component, the parent state is successfully updated. 在我的子页脚组件中,父状态已成功更新。 However, the footer component doesn't re-render to reflect the parent's updated state.
但是,页脚组件不会重新呈现以反映父级的更新状态。
Here's the footer component code that isn't getting re-rendered: 这是不会重新渲染的页脚组件代码:
render() {
return (
<div className="blurt-panel-footer">
<UpvoteCount voteCount={this.props.voteCount}/>
Any help much appreciated. 任何帮助,不胜感激。
EDIT: There was some confusion as to how blurtfooter is called, so I'm including the code for how the panel is built inside a loop within LazyBlurtPanel component. 编辑:关于如何调用blurtfooter有点困惑,所以我包括了有关如何在LazyBlurtPanel组件内的循环内构建面板的代码。 Here's the code for that:
这是该代码:
for(let i=numRendered; i<renderCount; i++) {
if (this.props.blurts[i]) {
renderBlurts.push(
<div className='blurt-panel' id={(((i + 1) % 6) === 0) ? this.props.lazyElement : 'false'} key={i}>
<BlurtHeader blurt={this.props.blurts[i]} />
<div className='blurt-panel-body'>
<Sanitizer dirty={ this.props.blurts[i].text } />
{
(this.props.blurts[i].blurtImg !== 'false')? <img src={'/images/blurt/' + this.props.blurts[i].blurtImg} /> : ''
}
</div>
<BlurtFooter
voteCount={this.props.blurts[i].vote}
currentUser={this.props.currentUser}
blurtId={this.props.blurts[i]._id}
blurtIndex={i}
handleUpvoteState={this.props.handleUpvoteState}
key={this.props.blurts[i]._id} //Tried with and without key here..
/>
</div>
);
}
}
Try changing how BlurtFooter
is called. 尝试更改
BlurtFooter
的调用方式。 Even if this doesn't fix it it will still be more maintainable code 即使不能解决问题,它仍将是更具可维护性的代码
render() {
const { currentUser, blurts, lazyElement, handleUpvoteState } = this.props;
return (
<Fragment>
{
blurts.filter(x => x).map((blurt, index) => (
<div className="blurt-panel" id={(((index + 1) % 6) === 0) ? lazyElement : 'false'} key={blurt._id}>
<BlurtHeader blurt={blurt} />
<div className="blurt-panel-body">
<Sanitizer dirty={blurt.text} />
{
blurt.blurtImg !== 'false' &&
<img src={`/images/blurt/${blurt.blurtImg}`} />
}
</div>
<BlurtFooter
voteCount={blurt.vote}
currentUser={currentUser}
blurtId={blurt._id}
blurtIndex={index}
handleUpvoteState={handleUpvoteState}
/>
</div>
)
}
</Fragment>
);
}
There are a lot of other improvements that can be made, but see how that works, especially setting key
correctly is a must. 可以进行很多其他改进,但是要了解其工作原理,尤其是正确设置
key
是必须的。
I'm not sure what that id
is on the div
but that looks fishy as well and shouldn't be there. 我不确定
div
上的id
是什么,但是看起来也很脏,不应该在那里。
Also the part blurts.filter(x => x)
shouldn't be needed, so state should be improved to not need that 同样也不需要部分
blurts.filter(x => x)
,因此应该改进状态以使其不需要
Updated : Make sure to take latest code above 更新 :请确保采用上面的最新代码
State should always update in a nonmutating way. 状态应始终以不变的方式进行更新。 This way react core library could understand there is a change in data.
通过这种方式,反应核心库可以了解数据发生了变化。 Array and objects use reference pointers in memory.
数组和对象在内存中使用引用指针。 So even if we update a value inside those reffrence type variables it won't affect the original memory location of those variables.
因此,即使我们在这些反射类型变量中更新值,也不会影响这些变量的原始内存位置。 So create a new variable in memory and copy the state that you need to update and then set the state by using the new variable.
因此,请在内存中创建一个新变量,然后复制您需要更新的状态,然后使用新变量设置状态。 This way we can avoid this issue.
这样我们可以避免这个问题。 Also you can create a nonmutating structure using modern es6 + methods.
您也可以使用现代es6 +方法创建一个不变结构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.