简体   繁体   English

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

[英]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.

相关问题 我们可以将 setState 作为 props 从一个组件传递到另一个组件,并在 React 中从子组件更改父状态吗? - Can we pass setState as props from one component to other and change parent state from child component in React? 从子组件更改父组件状态 - Change parent component state from child component 我们可以在 React 中将 props 从 Parent 传递给 Child 组件,并将 props 设置为子组件的 state 吗? - Can we pass props from Parent to Child component in React, and set the props as state of child component? 子组件无法识别父组件的道具更改 - Child component not recognizing props change from parent component 无法将状态从子组件更改为父组件 - Cannot change state from child to parent component 如何从子组件更改父状态? - How to change parent state from child component? 子组件未从父状态更改更新 - Child component is not updating from parent state change 当父组件改变状态时,子组件不会获得新的道具(功能组件) - Child component not get new props when parent component change state ( Functional Component ) 在选择选项更改时将道具从子组件传递给父组件 - Pass props from child component to parent on select option change 从 vuejs2 中的子组件更改父道具 - change parent props from child component in vuejs2
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM