2017-04-10 65 views
0

在一个redux应用程序中可以说它是一个博客。 国家可以像Redux对象的建立索引

{ 
    Posts: { 
    1:{day:'2016-03-13', id:1}, 
    2:{day:'2016-03-14',id:2}, 
    ..... 
    } 
} 

现在,在一定的分量我要显示某一天的所有帖子,我可以用Array.filter让这一天的帖子过滤所有的职位,但是这意味着,如果我每次组件刷新后都会有1000次重新计算整个过滤器。

所以在这种情况下,我认为它的更好,如果我在终极版商店类似

{ 
    PostsByDate: { 
    '2017-03-13': [1,2], .. Etc 
    } 
} 

一个索引,如何建立这样的指标,并确保其始终与岗位同步对象?

回答

1

如果你有很多数据(+1000篇博客)存储在客户端,你可能会想到分页和在服务器端运行过滤器。过滤器的计算成本应该很低,但是实际上取决于您使用的过滤器的类型,如果您使用每篇博文的正文进行过滤,很可能您会遇到性能问题。但是,如果过滤成本很低,加入完整的帖子集合的id数组的成本可能非常相似,所以在您提出的体系结构中应该没有显着的性能增益。这就是说,我会通过在一个数组内部显示post id的集合并在每次更改任何过滤器时更新该数组来完成此操作。如果没有过滤器,则数组为undefined,并显示所有帖子。

动作创建者

function filterPosts(filter) { 
    return { type: "FILTER_POSTS", filter }; 
} 

减速器

switch (action.type) { 
    ... 
    case "FILTER_POSTS": 
    return { 
     ...state, 
     PostsFiltered: action.filter 
     ? Posts.filter(action.filter).map(p => p.id) 
     : undefined 
    }; 
    ... 
} 

容器

container = connect(
    state => ({ ... }), 
    dispatch => bindActionCreators({ 
    onFilter: filterPosts, 
    onRemoveFilter: filterPosts.bind(null, undefined) 
    }, dispatch) 
)(Component); 

组件

filter() { 
    // Use whatever filter you want here 
    this.props.onFilter(...); 
} 
removeFilter() { 
    this.props.onRemoveFilter(); 
} 
render() { 
    ... 
    { 
     this.props.postsFiltered 
     ? this.props.posts.filter(p => this.props.postsFiltered.contains(p.id)) 
     : this.props.posts 
    } 
    ... 
} 

不要收藏奋斗,使用在官方终极版文档推荐Immutable

0

有一件事是构建指数数据。我的收藏状态最小结构是 Map({ byId: Map(), allIds: List([]) }) 其中byId地图基本上就是您在Posts散列中所拥有的。把你的redux商店看作是一个客户端数据库,如果你至少有一些后端经验IMO,这种思维方式确实有帮助。通过键查询地图是O(1)操作,所以这可以让你真正快速地获取id(想想SELECT * FROM POSTS WHERE id = your_id LIMIT 1)。现在

,allIds只是这是在byId键是有用的,当你在显示数据的列表中的所有ID列表 - 列表组件刚刚ID列表和每一个人ID传递给孩子ListItem组件,这也是连接到REDEX商店并使用简单选择器获取其mapStateToProps函数中的单个项目:selectPost(state, postId) { return state.posts.getIn(['byId', postId]) }

这给了你巨大的性能提升,特别是如果PostsList组件使用重新选择功能来缓存取id列表,因为如果你重新排列集合,作出反应处理它使用key道具聪明的办法,这应该是帖子的ID在你的情况 - 所以重新投降非常快。此外,如果某些帖子发生变化,则只有这个单独的帖子组件需要重新渲染。

您可以通过引入额外的指标为您的具体使用情况进一步采取这种做法位:如果你想通过某个用户来显示所有的帖子,你可以在这种情况下添加byUserId: Map(<lists of post ids>)更快的查找。完全像关系数据库索引一样,它的概念也是一样。

在rails中,每个模型都有updated_at timestamp字段,所以简单缓存可以检查后端获取集合的最新updated_at,并将其与头部进行比较,如果客户端值比客户端值晚,则客户端可以使用它发送所有api请求客户数据不陈旧和后端可以即时对应的头回应,它像2-5毫秒的响应,然后客户端可以完全绕过获取JSON,分析它,并输送到减速机的功能,所以很多的客户端的性能提升了。这样,你的组件都可以在componentDidMount只是火API请求,没有任何复杂的逻辑和高速缓存层将处理剩下的

+0

此外,你应该完全用于快速和稳健的集合immutable.js。我的所有模型基本上都是immutable.js记录,与本地JavaScript集合相比,处理集合是天堂。不变性也有助于在这里的表现。请参阅React.PureComponent和mapStateToProps文档,了解redux如何为连接组件实现shouldComponentUpdate。 此外,分页是必不可少的,加上你的后台+客户端简单的缓存机制来绕过所有这些API调用某种HTTP缓存有很大帮助 –