【发布时间】:2019-11-26 14:18:21
【问题描述】:
我的应用程序部分使用了 4 个组件,1 个父组件和 3 个子组件。正如预期的那样,父组件处理所有状态并通过 props 将值传递给子组件。
父组件包含更新状态更改的方法,也通过 props 传递。子组件除了组件方法外没有状态,它们仅使用 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 将数据发送到 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}
/>
当我打电话时
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>
);
}
}
【问题讨论】:
-
let blurts = JSON.parse(JSON.stringify(this.state.followingBlurts));试试这个。 -
@sk01 我的初始状态将 followingBlurts 设置为一个数组...为什么要切换到对象表示法?正如我的问题中提到的,状态实际上更新没有问题。不过谢谢!
-
状态改变是异步的。如果它工作正常,则状态更改不应反映在控制台中。这里的问题是当您使用扩展运算符时,数组引用是相同的。因此,您正在直接更改该数组。 Json stringify 会解决这个问题。
-
@sk01 我的描述有点误导。状态更改反映在控制台中,但它总是落后一个数字(由于您提到的异步行为,顺便说一句,良好的观察),但我可以验证它在第二次按下按钮后更新状态(upvote)。而且我只直接对数组进行更改,这是状态数组的浅拷贝......只是为了方便而尝试了你的解决方案,我的朋友不走运。
-
尝试在
LazyBlurtsPanel的render()方法中添加console.log,以查看状态更改后是否正在重新渲染。如果我是对的,您正在循环渲染BlurtFooter,那么您应该会看到有关缺少关键属性的警告。不确定是否会导致此问题,但请尝试添加key={this.props.blurts[i]._id}
标签: javascript reactjs