繁体   English   中英

子项道具不反映父项的状态变化

[英]Child component props not reflecting state change from parent

我的应用程序中涉及的部分是利用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将数据发送到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>
      );
  }
}

尝试更改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是必须的。

我不确定div上的id是什么,但是看起来也很脏,不应该在那里。

同样也不需要部分blurts.filter(x => x) ,因此应该改进状态以使其不需要

更新 :请确保采用上面的最新代码

状态应始终以不变的方式进行更新。 通过这种方式,反应核心库可以了解数据发生了变化。 数组和对象在内存中使用引用指针。 因此,即使我们在这些反射类型变量中更新值,也不会影响这些变量的原始内存位置。 因此,请在内存中创建一个新变量,然后复制您需要更新的状态,然后使用新变量设置状态。 这样我们可以避免这个问题。 您也可以使用现代es6 +方法创建一个不变结构。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM