我使用Redux和React Native制作了类似的功能。
我有一个初始状态为posts = []
的减速器,我的减速器看起来像
const initialState = {
posts: []
};
function postReducer(state = initialState, action) {
switch (action.type) {
case FETCH_POSTS:
return {
...state,
posts: action.posts
};
case LIKE_POST:
return {
...state,
posts: state.posts.map(post => {
if (post._id === action.postId) {
return {
...post,
likes: !!post.likes ? post.likes.concat(action.userId) : [action.userId]
}
}
return post;
})
};
case UNLIKE_POST:
return {
...state,
posts: state.posts.map(post => {
if (post._id === action.postId) {
return {
...post,
likes: post.likes.filter(userId => userId !== action.userId)
}
}
return post;
})
};
default:
return state
}
};
我知道我不能在我的状态中改变posts
数组,因此我必须返回一个新的帖子数组,其中我修改了用户试图喜欢/不同的帖子。
它似乎工作得很好,但它的速度令人生畏。我只有很少的帖子,但我仍需要等待几秒钟才能看到它。
这是正确的做法吗?我是否正确地将我的帖子存储为状态中的简单数组?我不确定替代方案是什么,但我在例如GitHub repo中看到它可以做得与众不同,尽管我并不完全理解它的结构。
答案 0 :(得分:0)
你是对的,这是缓慢而乏味的,但如果你想确保不改变状态并坚持建议的正确模式,这是必要的。
那说你有几个选择,一个显而易见的就是帮助functions
解决你遇到的常见问题,但是(个人)更好的解决方案是使用 ImmutableJS
< / strong>即可。它将为您提供三件事:
首先,它保证您不会改变状态,因为所有更改都会返回一个新的不同副本。
第二个是一个方便的API,它允许您轻松地进行突变,而不是使用笨拙的语法来解决vanilla javascript。
第三个是更小的好处,但您可以访问不可变类型,例如List
,Map
,各种Collections
,并使用{{1}定义您自己的类型我推荐用于每个reducer状态,因为你可以声明状态的形状,只改变定义的属性,而不是添加新的属性。
使用Records
减速器的一部分将如下所示:
Immutable
如果你在case FETCH_POSTS:
return state.set('posts', action.posts);
case LIKE_POST:
let posts = state.posts.map( (p) => {
if (p.id === action.postId) {
return p.set('likes', 'something');
}
return p;
}
之外建立你的州,那就更令人兴奋了,所以你会有:
Record
然后,您将拥有export default Record({
posts: List(),
}, 'SocialRecord');
或state.get('posts')
并且state.posts
具有immutable
功能Record
拥有getters
。
查看文档以获取更多信息:
<强> Immutable Documentation 强>