My React Firebase app renders a series of posts that each render a list of comments:
PostList
PostSummary
CommentList
Comment
PostList and CommentList each query a different collection (e.g. "posts" and "comments") in Firebase. The query for CommentList should pull just those comments that match the post id of the parent.
Strangely, for every Post on the page, the comments match the database for only the last Post on the page. Through console.logs I've determined that at one point, the right comments are present in each CommentList, but for some reason the components re-render an additional time with the last PostSummary's post id regardless of which PostSummary is their parent.
How is it possible the CommentLists are accessing a postId that should not be in their props?
const PostList = (props) => {
const { posts } = props
return (
<div>
{posts && posts.map(post => {
return (
<PostSummary post={post} key={post.id} />
)
})}
</div>
)
}
const mapStateToProps = (state) => {
return {
posts: state.firestore.ordered.posts
}
}
export default compose(
connect(mapStateToProps),
withRouter,
firestoreConnect([
{ collection: 'posts',
orderBy: ['created_At', 'desc'],
limit: 3 }
])
)(FullPostList)
const PostSummary = ({ post }) => {
//other code ommitted
return (
<div className="flex">
<div className="comments text-sm md:mx-0 mx-4 space-y-2">
<CommentList postId={post.id} />
</div>
</div>
)
}
const CommentList = (props) => {
const { comments, postId } = props
return (
<ul>
{comments && comments.map((comment,i) =>
<Comment comment={comment} key={i} />
)
}
</ul>
)
}
const mapStateToProps = (state, ownProps) => {
return {
comments: state.firestore.ordered.comments
}
}
export default compose(
connect(mapStateToProps),
withRouter,
firestoreConnect(props => [
{ collection: 'comments',
where: ['postId', '==', props.postId],
orderBy: ['created_At', 'desc'] }
])
)(CommentList)
As Tarik pointed out, the issue was using the same redux store variable name for multiple different groups of comments at the same time. Easiest way around it seems to be dynamically naming each group of comments - so instead of state.firestore.ordered.comments
, just do state.firestore.ordered[`${ownProps.recipeId}-comments`]
Full solution:
const CommentList = (props) => {
const { comments, recipeId } = props
return (
<ul>
{comments && comments.map((comment,i) =>
<Comment comment={comment} key={i} />
)
}
</ul>
)
}
const mapStateToProps = (state, ownProps) => {
return {
comments: state.firestore.ordered[`${ownProps.recipeId}-comments`]
}
}
export default compose(
connect(mapStateToProps),
withRouter,
firestoreConnect(props => [
{
collection: 'comments',
where: ['recipeId', '==', props.recipeId],
orderBy: ['created_At', 'desc'],
storeAs: `${props.recipeId}-comments`
}
])
)(CommentList)