有没有更好的方法来处理这个redux重构分支用例?

时间:2017-10-12 11:02:45

标签: reactjs redux recompose

我有一个名为PartyDetails的组件,它需要ajax调用提取的数据。我想在ajax请求正在进行时显示Loading组件。

问题是,为了确定数据是否已加载,我需要访问商店。这就是我的增强效果:

const enhance = compose(
    propSetter,
    lifecycleEnhancer,
    loading,
)

export default enhance(PartyDetails)

其中propSetter是:

const propSetter = connect((state) => {
    const { party } = state
    const { dataLoaded } = party
    // for some reason state does not contain match, and I'm resorting to routing
    const { routing: {location: { pathname }}} = state
    const involvedPartyId = pathname.substring(pathname.lastIndexOf('/') + 1)
    return { dataLoaded, involvedPartyId }
}, {loadParty})

lifecycleEnhancer是:

const lifecycleEnhancer = lifecycle({
    componentDidMount() {
        this.props.loadParty(this.props.involvedPartyId)
    }
})

loading是(请注意,在这种情况下,dataLoaded来自connect中已完成的上一个propSetter

const loading = branch(
    ({dataLoaded}) => dataLoaded,
    renderComponent(connect(mapStateToProps, mapDispatchToProps)(PartyDetails)),
    renderComponent(Loading)
)

所以基本上,如果数据已被提取,我使用第二个连接来获取PartyDetails的相关道具。

我几天前刚开始学习recompose,但我找不到适合我用例的示例。以上是我在阅读完文档后想出的内容,以及其他文章中的一些例子。

我正在做一个好办法吗?这可以用更好的方式完成,也许不需要2 connect次呼叫吗?

1 个答案:

答案 0 :(得分:0)

您可以在一个连接中编写映射状态和调度到道具的所有逻辑:

export default compose(
  connect(
    state => {
      const { party } = state;
      const { dataLoaded } = party;
      const { routing: { location: { pathname } } } = state;
      const involvedPartyId = pathname.substring(pathname.lastIndexOf("/") + 1);

      // also put here your `mapStateToProps` code

      return { dataLoaded, involvedPartyId };
    },
    {
      loadParty
      // the same here, append `mapDispatchToProps` logic
    }
  ),
  lifecycle({
    componentDidMount() {
      this.props.loadParty(this.props.involvedPartyId);
    }
  }),
  branch(
    ({ dataLoaded }) => dataLoaded,
    renderComponent(PartyDetails),
    renderComponent(Loading)
  )
  // as `branch` is returning HOC, we need to provide empty component to it in
  // order to render whole component
)(createSink());