redux app据我所知,维护状态树的正确方法是对其进行规范化,尽可能地展开数据并使用combinereducer创建状态树的切片。
示例包含帖子和用户的应用
const rootReducer = combineReducers({
user:userReducer,
posts:postsReducer,
});
const store = createStore(rootReducer);
给出帖子数组保留所有帖子init,State.posts
看起来像
let initialState = {
byId:{1:{id:1,title:'post1'}},
ids:[1],
meta_data:{unread:1,old:0}
}
现在,如果我们有大约10,000个帖子,我们最终会得到state.post.ids.length === 10000
,这很好,
问题是。,因为我们的reducer在每次时需要更新时返回一个新状态,例如我们需要将meta_data.unread更新为等于0,我们将返回一个新的Post对象。
return object.assign({},state,{meta_data:{unread:0,old:1}})
将重新渲染使用state.post
树的任何属性的所有选择器和组件!
这听起来像是个问题吗?**我们想要的只是更新未读的计数器.. 为什么要重新计算帖子的所有选择器和组件?
所以我有这个想法可能是state.posts也应该组成使用combineReducers使每个attr。帖子应该有自己的减速器。
将postsReducer拆分为多个
postsMainReducer, ==> deal with adding or removing posts
postMeta_dataReducer, ==> deal with meta_data of posts
singlePostReducer ==> Now this is dynamic !! how can i create such ??
这是正确的吗?我增加的复杂性超过了需要?
- >有人可以向我们展示已经运行的企业应用状态树的图片吗?所以我们可以从中学习如何组织国家?
答案 0 :(得分:3)
重要的是要注意Redux商店实际上只有一个reducer功能。商店将当前状态和调度操作传递给那个reducer函数,并让reducer适当地处理事情。
显然,尝试在单个函数中处理每个可能的操作并不能很好地扩展,只是在函数大小和可读性方面,因此将实际工作拆分为可由顶层调用的单独函数是有意义的减速器。特别地,常见的建议模式是具有单独的子缩减器功能,其负责管理对特定键处的特定状态切片的更新。 Redux附带的combineReducers()是实现此目的的众多可能方法之一。我们还强烈建议您将商店状态保持平稳且尽可能正常化。但最终,您可以按照自己的方式负责组织减速器逻辑。
然而,即使您碰巧有许多不同的独立子减速器,甚至有深度嵌套状态,减速器速度也不太可能成为问题。 JavaScript引擎能够每秒运行大量的函数调用,并且大多数子减速器可能只是使用switch语句并默认返回现有状态以响应大多数操作。
如果您真的关心reducer性能,可以使用诸如redux-ignore(https://github.com/omnidan/redux-ignore)或reduxr-scoped-reducer(https://github.com/chrisdavies/reduxr-scoped-reducer)之类的实用程序来确保只有某些reducer可以监听具体行动。您还可以使用redux-log-slow-reducers(https://github.com/michaelcontento/redux-log-slow-reducers)进行一些性能基准测试。
以下是我最常提到的项目 -
这些是Redux的实际用途。
以下是一些链接:
https://github.com/andrewngu/sound-redux
https://github.com/echenley/react-news
https://github.com/paulhoughton/remember/
https://github.com/paulhoughton/mortgage/
https://github.com/benoitvallon/react-native-nw-react-calculator
https://github.com/jfurrow/flood
https://github.com/FH-Potsdam/shifted-maps
https://github.com/quirinpa/2post
答案 1 :(得分:1)
将重新渲染使用任何选择器和组件的所有选择器和组件 state.post tree的属性!
这不确定,当商店的不相关属性发生变化时,组件不必重新呈现。如果你的组件是PureComponent,当属性的引用(原始道具的值)等于它们最后一次渲染时,它将不会被重新渲染。
var foo = { a: [1, 2, 3], someCount: 1 };
var bar = Object.assign({}, foo, { someCount: 2 });
console.log(foo.a === bar.a);
// true
reducer中返回的状态确实是一个新对象,但是你的posts数组在赋值后仍然是同一个数组(相等的引用)。因此,如果使用PureComponent,React会很好地处理它。
您可能会偶然发现下一步:如果您在选择器中使用从商店或多个商店派生的派生数据,您可以使用reselect来memoize结果,以便引用保持不变 - 不需要重新渲染。 An article describes the problem with creating new arrays for derived or empty data in each render cycle.