通过选择器将静态道具发送到组件,最佳做法

时间:2017-05-16 09:03:20

标签: react-native redux

我有时需要向组件发送静态道具,但数据实际上来自我的Redux商店。即我需要访问状态才能获取数据。

对于静态,我的意思是这个数据在组件的生命周期内不会改变,所以我不想在每个渲染的商店中选择它。

这是我最初解决它的方法(mapStateToProps部分):

  (state, ownProps) => ({
    journalItemType: selectJournalItemType(state, ownProps.journalItemTypeId)
  })

组件获取 JournalItemTypeId ,mapStateToProps在商店中查找它并将journalItemType发送到组件。 JournalItemType是静态元数据,不会经常更改,当然也不会在组件的生命周期内更改。

static propTypes = {
  journalItemType: ImmutablePropTypes.map.isRequired,
}

这个问题是我在每次渲染时调用选择器。不是很大的表现,但无论如何都感觉不对。

所以,我改为:

  (state, ownProps) => ({
    getJournalItemType: () => selectJournalItemType(state, ownProps.journalItemTypeId)
  })

我在组件构造函数中做的第一件事是调用getJournalItemType并将结果存储在本地状态。这样选择器只被调用一次。

static propTypes = {
  getJournalItemType: PropTypes.func.isRequired,
}

constructor(props) {
  super(props);
  this.state = {
    journalItemType: props.getJournalItemType()
  }
}

问题:

这是正确的方法吗?

另一种方法是让组件了解状态,以便组件可以调用选择器本身。但我认为将国家排除在组件之外会更加清晰。

我也可以在调用链中调用选择器并获取静态数据,但我也没有状态

澄清:

如果是静态数据,为什么我会将 JournalItemTypes 存储在Redux存储中?所有应用程序元数据都在我的redux商店中,因此可以从服务器轻松刷新。通过将其保存在Redux中,我可以像处理同步传奇中的所有其他数据一样处理元数据。

在Mika回答后补充说明

我需要使用本地状态,因为组件是一个非常复杂的输入形式,具有各种输入(输入字段,相机,qr读取器,基于输入的实时更新SVG草图)。

我的应用中的JournalItem是“全有或全无”。即如果填写了每个必填字段,则允许用户保存该项目。我的商店坚持使用磁盘,所以我不想经常访问商店。所以JournalItem-object(实际上是一个Immutable.map)一直处于状态,直到它准备好被保存。

我的选择器通过重新选择进行记忆。这使我的第一个解决方案对性能的影响更小。但它仍然感觉不对。

由于其他事件,组件会通过props更新,因此它会不时重新渲染。

1 个答案:

答案 0 :(得分:1)

这里有几个不同的选项:

选项1:原始方式

这是最基本,最重要的' Redux'这样做的方式。如果您的selectJournalItemType功能适度轻,则您的应用不会受到很大的性能影响,因为仅在商店更新according to react-redux docs时调用mapStateToProps

选项2:构造函数

通常建议避免在Redux中使用Component的状态。有时它是必要的(例如有输入的表格)但在这种情况下它可以,并且在我看来应该避免。

选项3:优化选项1

如果您的功能在计算上非常昂贵,那么至少有几种方法可以优化原始解决方案。

在我看来,其中一个更简单的是optimizing the react-redux connect。简短的例子:

const options = {
  pure: true, // True by default
  areStatesEqual: (prev, next) => {
    // You could do some meaningful comparison between the prev and next states
    return false;
  }
};

export default ContainerComponent = connect(
  mapStateToProps,
  mapDispatchToProps,
  mergeProps,
  options
)(PresentationalComponent);

另一种可能性是创建memoized function using Reselect