Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 对象的Redux生成索引_Design Patterns_Redux_React Redux_Flux - Fatal编程技术网

Design patterns 对象的Redux生成索引

Design patterns 对象的Redux生成索引,design-patterns,redux,react-redux,flux,Design Patterns,Redux,React Redux,Flux,在redux应用程序中,让我们说它是一个博客。 国家可以看起来像 { Posts: { 1:{day:'2016-03-13', id:1}, 2:{day:'2016-03-14',id:2}, ..... } } 现在,在某个组件中,我想显示某一天的所有帖子,我可以使用Array.filter筛选所有帖子,以获取当天的帖子,但这意味着,如果每次组件刷新时我都有1000篇帖子,它将重新计算整个过滤器 因此,在这种情况下,我认为最好在redux存储中有一个索引,

在redux应用程序中,让我们说它是一个博客。 国家可以看起来像

{
  Posts: {
    1:{day:'2016-03-13', id:1},
    2:{day:'2016-03-14',id:2},
    .....
  }
}
现在,在某个组件中,我想显示某一天的所有帖子,我可以使用Array.filter筛选所有帖子,以获取当天的帖子,但这意味着,如果每次组件刷新时我都有1000篇帖子,它将重新计算整个过滤器

因此,在这种情况下,我认为最好在redux存储中有一个索引,比如

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

那么,如何建立这样的索引并确保它始终与posts对象同步呢?

如果您在客户端存储了大量数据(+1000篇博客文章),您可能会考虑在服务器端分页并运行过滤器。过滤器的计算成本应该很低,但这实际上取决于您使用的过滤器的类型,如果您使用每个博客文章的正文进行过滤,则很可能会出现性能问题。但是,如果过滤的成本很低,那么将ID数组与完整的帖子集合连接起来的成本可能非常相似,因此您所建议的体系结构不会带来显著的性能提升

也就是说,我会在一个数组中显示post ID集合,并在每次过滤器更改时更新该数组。如果没有过滤器,那么数组是未定义的,您将显示所有帖子

动作创建者

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);
减速器

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);
容器

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
    }
  ...
}

不要纠结于收集,使用

官方redux文档中推荐的一件事是为数据建立索引。我的集合状态的最小结构是

Map({
  byId: Map(),
  allIds: List([])
})
其中,
byId
map基本上就是您在
Posts
hash中拥有的内容。把你的redux存储想象成一个客户端数据库,如果你至少有一些后端经验,这种思维模式确实会有所帮助。按键查询映射是一种O(1)操作,因此这可以让你真正快速地按id抓取(想想
SELECT*FROM POSTS,其中id=your_id LIMIT 1

现在,AllID只是所有id的列表,这些id是
byId
中的键,在显示数据列表时非常有用-列表组件只有id列表,并将每个id传递给子
ListItem
组件,它们还连接到redux store,并使用简单的选择器在其
mapStateToProps
函数中获取单个项目:
selectPost(state,postId){return state.posts.getIn(['byId',postId])

这会给您带来巨大的性能提升,尤其是当组件使用重新选择功能缓存id的获取列表时,因为如果您重新排序集合,React会使用
道具以智能方式处理它,在您的情况下,它应该是post id-因此重新加载非常快。此外,如果某些post发生更改,则只需重新提交此单个post组件

通过为您的特定用例引入额外的索引,您可以进一步采用这种方法:如果您想显示某个用户的所有帖子,您可以添加
byUserId:Map()
,以便在这种情况下更快地查找。和关系数据库索引完全一样,它的概念是相同的


在rails中,每个模型都更新了时间戳字段上的\u,因此简单缓存可以检查后端获取的集合的最新更新的\u,并将其与标头进行比较,您的客户端可以将标头与所有api请求一起发送,如果其注释晚于客户端值,则客户端数据不会过时,后端可以立即响应相应的标头,响应时间为2-5毫秒,然后客户端可以完全绕过获取json、解析json并将其提供给reducer函数,所以客户端的性能也有了很大提高。这样,您的组件就可以在componentDidMount上触发api请求,而无需任何复杂的逻辑,而缓存层将处理其余部分

。此外,您应该完全使用immutable.js来实现快速和正常的收集。我所有的模型基本上都是不可变的.js记录,与本机javascript集合相比,使用集合简直是天方夜谭。不变性也确实有助于提高性能。请参阅React.PureComponent和mapStateToProps文档,了解redux如何为连接的组件实现shouldComponentUpdate。此外,分页是必不可少的,加上后端的某种http缓存+客户端上的简单缓存机制,可以绕过所有这些api调用,这会有很大帮助