简体   繁体   中英

Child component does not update when parent state changes

I have a situation where I am passing props from parent to child component. The parent is connected to the redux store and, from the child (using bindActionCreators), I dispatch some action to change the state in the store which the parent is connected to. Now, when I change the state in the store from the child, the parent gets updated but the child does not. The (logic)/(user action) to cause that change originates in the child. I got around the problem by dispatching the action from the parent itself and sending the necessary information from the child to the parent through a callback. Now, the parent and child both update. The code is too big to post here and I have at least got the code to work. I am just wondering why the child does not update in the case where the action is dispatched from the child, can someone point out if I am missing some basic concept here or it could be something more complicated that could only be resolved by going into the code in detail.

(Simplified code included after edit). This is the version where the child dispatches the action to modify the store, the parent updates but the child does not. If I move the dispatch to the parent itself, then the child starts updating.

Parent:

class Table extends Component {
render() {
return (
  <div className = 'table-container'>
      {
      this.props.columns.map((column) => 
       <div key = {i}>
         {column}
       </div>
      }
      <TableHeader
      columns = {this.props.columns}
      />
  </div>
  )
 }
}

function mapStateToProps(state){
  return {
    columns: state.columns,
  };
}

export default connect(mapStateToProps, null)(Table);

Child:

class TableHeader extends Component {

  constructor(props){
    super(props)
    this.getColumnHeadings.bind(this)
  }


  onDragStart(ev, i) {
    ev.preventDefault();
  }

  onDragOver(ev) {
    ev.preventDefault();
  }

  onDrop(ev, i) {
    ev.preventDefault();
    this.props.changeColumns({index: i})
  }


  getColumnHeadings = (columns) => {
    return this.props.columns.map((column, i) =>
        <div key = {i}
        draggable
        onDragStart = {(ev) => this.onDragStart(ev, i)} 
        onDragOver = {this.onDragOver} 
        onDrop = {(ev) => this.onDrop(ev, i)}
        >
        {column}
        </div>
    )
  }


  render() {
    return (
          <div className = 'table-header1'>
            {this.getColumnHeadings(this.props.columns)}
          </div>
    )
  }
}

function matchDispatchToProps(dispatch){
  return bindActionCreators({changeColumns: changeColumns}, dispatch)
}

export default connect(null, matchDispatchToProps)(TableHeader);

Action Creator:

export const changeColumns = (changeInfo) => ({ type: "change columns", payload: changeInfo});

Thanks!

You need to pass state to props in child component when you are connecting to the redux store using connect .

or else your child component wouldn't know that the state has been changed (let redux store notify your child component).

(actually it does if you pass it to child component via props from Table but as you stated, that's not what you want and there is no point of using Redux in the first place.)

function mapStateToProps(state){
  return {
    columns: state.columns,
  };
}

function matchDispatchToProps(dispatch){
  return bindActionCreators({changeColumns: changeColumns}, dispatch)
}

export default connect(mapStateToProps, matchDispatchToProps)(TableHeader);

I think the reason for this could be once you connect your component to Redux Store through connect HOC, your component is updating it's props according to how Redux store is changed & when mapStateToProps is triggered. Seems like it doesn't render when props are passed from the parent anymore. Had that experience & had to pass the props through parent components as props.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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