Paulos3000 Paulos3000 - 1 month ago 21
Javascript Question

Filtering array elements in React/Redux

I have a React application which filters users and posts. My navbar can link to either users, posts.

Clicking on posts brings up a list of every post made, by all users (with some extra meta information for each one).

Here is my Posts component:

export default class Posts extends Component {
render() {
return (
<div>
{this.props.posts.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}
}


On the users page, each user has a sublink posts. What I want is to be able to click on posts for that user and it to take you to a posts page (like above), but only list the posts for that user.

The posts array looks a bit like this:

[
{ id: 1,
userId: 1
},
{ id: 2,
userId: 1
},
{ id: 3,
userId: 2
},
{ id: 4,
userId: 3
},
{ id: 5,
userId: 3
}
]


Say I clicked on the user with
userId
of
3
, and only wanted to display his/her posts. What is the best way to do this?

I know I can use react-router to pass the
userId
to the URL, and then pull that back into the component, but I'm not sure how to use this once the Posts component renders. Ultimately I want it to render the posts array filtered to the userId route param, else render all posts. Is this right approach?

Any help appreciated.




UPDATE:



Ok, I know this is not an elegant solution, but I want to start off with a solution, then I will 'trim it down', so to speak.

There's a bug in this code which I cannot figure out:

render() {

const {userId} = this.props.params

if(userId) {
const postsForUser = posts.filter( post => post.userId === userId )
return (
<div>
{postsForUser.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}
else {
return (
<div>
{this.props.posts.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}

} // end render()


When I log
userId
, it correctly logs the user id that I have just clicked on, so my
this.props.params.userId
variable is working correctly.

If I define
postsForUser
with a hardcoded integer, e.g.

const postsForUser = posts.filter( post => post.userId === 3 )


It returns the filtered array correctly.

So at this point it seems everything is working fine, except when I swap out the hardcoded id for the variable,
postsForUser
returns as an empty array.

Where am I going wrong?




UPDATE 2 (Fix):



For anyone facing this problem, I incorrectly returned the id from
this.props.params.userId
as a string, so instead I had to define it using
parseInt()
like this:

const userId = parseInt(this.props.params.userId)

Answer

You can simply use Array's filter method:

render(){
    return (
        <div>
            {
                if(this.params.userId) {
                    const postsForUser = posts.filter(post => post.userId == this.params.userId);
                    //renderPostList(postsForUser)
                } else {
                    //renderPostList(posts)
                }
            }
        </div>
    )
}