简体   繁体   中英

React component not re-rendering after props change

I am trying to filter a set of objects in the state whenever the user clicks on a button on my component. The logic of the filtering works fine, but when it gets back to the component, the filtered objects are missing and instead the property is undefined. Am I missing a lifecycle method?

The click event:

<div onClick={this.filterMyPosts}>My Posts</div>
...
<div>
    {this.renderPosts()}
</div>

filterMyPosts

filterMyPosts() {
   this.props.updateFilter("myPosts");
   // filtering function uses switch statement based on strings to filter posts
}

The component container:

const mapStateToProps = (state) => {
  return {currentUser: state.session.currentUser,
    posts: allPostsByFilter(state.posts, state.filter, state.session.currentUser.id, state.bookmarks)}
};

const mapDispatchToProps = (dispatch) => ({
  updateFilter: (filter) => dispatch(updateFilter(filter))
})

The filtering takes place in a different file, which returns the filtered events in an object. That logic has no errors.

The problem : By the time it gets to the following function, "posts" is undefined. So somewhere along the way, the filtered posts are not making it back to the component.

renderPosts() {
    return (
    <div className ="user-profile-posts">
      <ul>
       {Object.keys(this.props.posts).map(id => <PostIndexItem 
        key={`posts-index-item${id}`} 
        post={this.props.posts[id]}
        user={true}
        />)}
      </ul>
    </div>
    );
  }

EDIT - filter function

export const allPostsByFilter = (filter, currentUserId, posts) => {
  switch (filter) {
case "myPosts":

  let postKeys = Object.keys(posts).filter( (id) => {
    return(posts[id].user_id === currentUserId)
  });
  let userPosts = {}
  postKeys.forEach( (key) => userPosts[key] = posts[key])
  let newPosts = {}

  let postKeys = Object.keys(posts).filter( (id) => {
    return (Object.keys(userPosts).includes(id))
  });
  eventKeys.forEach( (key) => newPosts[key] = posts[key])

  return newPosts

default: 
      return posts

You lose this context when binding your action.

<div onClick={this.filterMyPosts}>My Posts</div>

Change the invocation to

<div onClick={() => this.filterMyPosts()}>My Posts</div>

This assures this in your filterMyPosts method. Without it, props is undefined.

State is missing posts as one of the property / reducer. events should be replaced by posts.

const mapStateToProps = (state) => {
  return {currentUser: state.session.currentUser,
    events: allPostsByFilter(state.posts, state.filter, state.session.currentUser.id, state.bookmarks)}
};

There is a mismatch in parameters between the allPostsByFilter call and the function definition.

The first parameter should be the filter. Instead posts is being passed as the first parameter.

The dispatch method - updateFilter should change the state of the filter for allPostByFilter to be triggered.

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