-
-
Save kadmil/ad715b26f14df17c781f to your computer and use it in GitHub Desktop.
const initPosts = [{ | |
id: 1, | |
author: 1, | |
comments:[1,2] | |
} | |
] | |
const initComments = [ | |
{id: 1, author: 1}, | |
{id: 2, author: 2} | |
] | |
const initAuthors = [ | |
{id:1, name:'1'}, | |
{id:2, name:'2'} | |
] | |
function posts(state = initPosts, action){ | |
return state | |
} | |
function comments(state = initComments, action){ | |
return state | |
} | |
function authors(state = initAuthors, action){ | |
return state | |
} | |
const PostFeed = (props) => ( | |
<div> | |
{props.posts.map(post => <PostComponent {...post}/>)} | |
</div> | |
) | |
const PostComponent = (props) => ( | |
<div> | |
<div>{props.author.name}</div> | |
{props.comments.map(comment => (<div>comment.author.name</div>))} | |
</div> | |
) | |
const mapStateToProps = (state) => { | |
const mappedPosts = state.posts.map(post => { | |
const author = state.authors[post.author] | |
const comments = state.comments.map(comment => ({ | |
...comment, | |
author: state.authors[comment.author] | |
})) | |
return {...post, author, comments} | |
}) | |
} |
@gaearon would it be faster than single mapping? Each connect()
would be fired on app state change, so we're basically 'distribute' this function between single PostComponent
nodes. It's not the re-rendering bothering me, plain mapping in case of many comments becomes an issue.
Can I ask you to create a project reproducing the perf issue? Then we can try to profile it. Otherwise it's just talk. :-)
@kadmil: Where did you end up with this finally?
I have a similar problem but with a slightly more expensive, and nested mapping and am wondering if using reselect
would help instead?
It seems that one advantage of the approach @Gaeron suggests here could be that not all the sub-components need to be re-rendered as they might need different parts of the mapping, and for a lot of them, the input might not change. For example, PostContent
might not need comments
and any change to those mappings will not re-render PostContent
.
@gaearon: Is this a good use-case for using reselect
instead of building a custom mapStateToProps
method? In general, whats a good way to think about reselect
vs mapStateToProps
?
Instead of doing
mapStateToProps
once and trying to recreate the tree structure, insteadconnect()
every component. Let each component receive its “primary” data as a prop (e.g.post
forPostComponent
,comment
forCommentComponent
—you don't have it yet,posts
forPostFeed
), but let each component grab the relevant "child props" byconnect()
ing each of them. For example, letPostComponent
grabcomments
asfunction mapStateToProps(state, ownProps) { return { comments: ownProps.post.comments.map(id => state.comments[id]) } }
and so on. This way you won't have to build any kind of expensive structure.