我有一个简单的路由器(使用redux-router
启动并切换到react-router
以消除变量)。
<Router history={history}>
<Route component={Admin} path='/admin'>
<Route component={Pages} path='pages'/>
<Route component={Posts} path='posts'/>
</Route>
</Router>
管理组件基本上只是带有一些导航的{this.props.children}
; 它不是connect
组件。
Pages组件是一个带有mapStateToProps()
的connect
组件, mapStateToProps()
所示:
function mapStateToProps (state) {
return {
pages: state.entities.pages
};
}
帖子更有趣:
function mapStateToProps (state) {
let posts = map(state.entities.posts, post => {
return {
...post,
author: findWhere(state.entities.users, {_id: post.author})
};
}
return {
posts
};
}
然后当我加载页面或在帖子/页面路由之间切换时,我在console.log()中得到以下内容。
// react-router navigate to /posts
Admin render()
posts: map state to props
Posts render()
posts: map state to props
Posts render()
posts: map state to props
// react-router navigate to /pages
Admin render()
pages: map state to props
Pages render()
pages: map state to props
所以我的问题是:为什么在路由更改时多次调用mapStateToProps
?
另外,为什么mapStateToProps
中的简单map
函数会导致它在Posts容器中第三次被调用?
我正在使用Redux文档中的基本logger
和crashReporter
中间件,并且它没有报告任何状态更改或崩溃。 如果状态没有改变,为什么组件会多次渲染?
根据react-redux
经验,您不应该在mapStateToProps
处理store属性,因为connect
使用了对绑定存储属性的浅层检查来检查diff 。
要检查是否需要更新组件, react-redux
调用mapStateToProps
并检查结果的第一级属性。 如果其中一个更改( ===
相等检查),组件将使用新的props更新。 在你的情况posts
改变( map
变换)每次mapStateToProps
被调用,所以你的组件更新每家商店的变化!
您的解决方案是仅返回商店属性的直接引用:
function mapStateToProps (state) {
return {
posts: state.entities.posts,
users: state.entities.users
};
}
然后在您的组件中,您可以定义一个按需处理数据的函数:
getPostsWithAuthor() {
const { posts, users } = this.props;
return map(posts, post => {
return {
...post,
author: findWhere(users, {_id: post.author})
};
});
}