我的应用程序中涉及的部分是利用4个组件,即1个父级和3个子级。如预期的那样,父组件处理所有状态并将值通过prop传递给子组件。
父组件包含用于更新状态更改的方法,这些状态更改也通过props传递。子组件除组件方法外没有其他状态,它们仅对视觉数据使用道具。
我遇到的问题是,当我调用更新父状态的方法时,父状态已成功更新(通过控制台进行了验证),但是通过其道具反映此状态的子组件却没有直观地呈现状态变化。
下面是代码,我将尽力解释:
父组件更新状态方法:
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.
}
父组件将状态传递给子道具:
<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}
/>
(上面)惰性面板组件然后通过props将数据发送到页脚子项:
<BlurtFooter
voteCount={this.props.blurts[i].vote}
currentUser={this.props.currentUser}
blurtId={this.props.blurts[i]._id}
blurtIndex={i}
handleUpvoteState={this.props.handleUpvoteState}
/>
当我打电话
this.props.handleUpvoteState(index)
在我的子页脚组件中,父状态已成功更新。但是,页脚组件不会重新呈现以反映父级的更新状态。
这里的页脚组件代码没有被重新渲染:
render() {
return (
<div className="blurt-panel-footer">
<UpvoteCount voteCount={this.props.voteCount}/>
非常感谢任何帮助。
编辑:关于如何调用blurtfooter存在一些困惑,因此我包括了有关如何在LazyBlurtPanel组件内的循环内构建面板的代码。这是该代码:
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>
);
}
}
答案 0 :(得分:1)
尝试更改BlurtFooter
的调用方式。即使不能解决问题,它仍将是更具可维护性的代码
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>
);
}
还有许多其他可以改进的地方,但是要知道它是如何工作的,尤其是必须正确设置key
。
我不确定id
上的div
是什么,但是看起来也很腥,不应该在那里。
也不需要blurts.filter(x => x)
部分,因此应改进状态以使其不需要
已更新:请确保在上面输入最新的代码
答案 1 :(得分:0)
状态应始终以不变的方式更新。通过这种方式,反应核心库可以了解数据发生了变化。 数组和对象在内存中使用引用指针。因此,即使我们在这些反射类型变量中更新值,也不会影响这些变量的原始内存位置。 因此,请在内存中创建一个新变量,然后复制您需要更新的状态,然后使用新变量设置状态。这样我们可以避免这个问题。 您也可以使用现代es6 +方法创建一个不变结构。