Redux在Reducer之间共享数据和操作的方法

时间:2017-09-30 21:02:52

标签: javascript redux

我正在开发一个分为多个功能的音乐应用程序:

  • library:显示可用内容,并允许用户浏览艺术家和专辑,并播放一首或几首曲目。州看起来像这样:

    图书馆{   tracksById:{...}   albumsById:{...}   artistsById:{...}   专辑:[]   艺术家:[] }

  • player:播放音乐的部分。只包含要播放的所有曲目的数组。还会显示要播放的曲目列表

等;问题是我想在所有功能之间共享tracksByIdalbumsByIdartistsById,因为每个相册都有一个艺术家属性,但这个属性只是一个id,所以如果我想要要在播放列表中的曲目名称附近显示艺术家姓名,我需要获取艺术家,并将其放入我的商店。我可以简单地将它们连接起来:

@connect(createStructuredSelector({
  player: (state) => state.player,
  library: (state:) => state.library
}), (dispatch) => ({
  actions: bindActionCreators(actions, dispatch)
}))

然后在我的播放列表视图中:

<div className="artist-name">{this.library.artistsById[track.artist].name}</div>

然而,这增加了特征之间的耦合,我发现它击败了多个减速器的目的。

另一种方法是创建一个新功能content,它只包含所需的动作和byId属性,以及最小的减速器,并且这个功能将由其他功能共享。但是,这意味着我必须为每个组件content添加一个新的道具,我需要添加操作。

我还可以创建一个服务,甚至可能是一个带有reducer和actions对象的函数,并添加一个逻辑,使它能够获取艺术家,专辑和曲目并将它们保存在商店中。我真的很喜欢这个想法,因为它减少了耦合,但是,它意味着我的状态中的重复数据,这意味着使用更多的内存。

我不是在寻找最好的方法,只是想知道是否还有其他方法以及每种方法的优缺点

1 个答案:

答案 0 :(得分:0)

我很确定我不完全理解你的问题,但我会分享一些想法。您是否尝试避免重复查询或重复的状态数据?

对象是快速词典

这一点重复:

{this.library.artistsById[track.artist].name}

如果library.artists是对象而不是数组,则

变得不必要。假设1和2是艺术家ID,artists将使用艺术家ID作为对象中的键:

{
   1: {name: 'Bob Marley', ...etc},
   2: {name: 'Damien Marley', ...etc}
}

这样,您只需使用ID:

即可从library.artists获取艺术家信息

{this.library.artists[track.artistId].name}

使用选择器功能

但你真正想要的是getArtistById(state, artistId){},你的reducer代码文件中的选择器函数。这使您可以随时重新排列状态,并且您的视图组件都不会受到影响。如果artists是关键字为艺术家ID的对象,则实现可能如下所示:

getArtistById(state, artistId){
    return state.library.artists[artistId]
}

我同意你的看法,即访问library.artistsById[track.artist].name会增加不必要的耦合。我永远不会将知道高级状态形状的代码放入视图组件中。 对于带有艺术家列表的示例播放列表视图,播放列表视图中的每个项目都是其自己的微小组件。容器看起来像这样:

import { getArtistById } from '../reducers/root-reducer'
const mapStateToProps = (state) => {
   const artist = getArtistById(state.library)
   return { artistName: artist ? artist.name : '' }
}
...

微小视图组件看起来像:

render() { 
    const {artistName} = this.props
    return <div className="artist-name">{artistName}</div> 
}

过早优化?

您可能过早地进行了优化。即使您将artistsalbums保留为数组,您的选择器功能也可以在数组中搜索ID。从一个只包含{ artists: [], albums: [], tracks:[] }的状态获取每个id的函数应该非常快,直到库变得非常庞大。