如何在react-redux-connect的@connect decorator中访问动态数据?

时间:2016-10-25 10:47:20

标签: reactjs asynchronous redux react-router react-redux

所以,我将react-async-connect与react-redux-connect结合使用,如下所示:

@asyncConnect([{
  deferred: true,
  promise: ({ params, store: { dispatch, getState } }) => {
    if (!isLoaded(getState(), params.userID)) {
      console.log('it was not already loaded')
      return dispatch(loadProfile(params.userID))
    }

    console.log('it was indeed already loaded')

  },
}])
@connect(
  state => ({
    profile: {???},
    error: state.publicData.profile.error,
    loading: state.publicData.profile.loading,
  }),
  { initializeWithKey }
)
export default class Profile extends Component {
  ...etc

基本上,asyncConnect会触发加载相关数据的操作,然后我使用@connect装饰器将此数据加载为下面Profile组件的道具。问题是,我想基于userId将用户配置文件数据加载到我的商店,因此数据的位置是"动态"。如何在@connect装饰器中访问params或其他globalState类型的东西?

假设用户的ID是1234,我需要的是这样的:

@connect(
  state => ({
    profile: state.publicData.users.1234,
    error: state.publicData.profile.error,
    loading: state.publicData.profile.loading,
  }),
  { initializeWithKey }
)

当然,userId位于params对象中,也位于路径本身中。我该如何访问?

修改

所以我应该更仔细地查看文档。事实证明你可以传递第二个ownProps参数,如下所示:

@connect(
  (state, ownProps) => ({
    profile: state.publicData.users[ownProps.params.userId],
    error: state.publicData.profile.error,
    loading: state.publicData.profile.loading,
  }),
  { initializeWithKey }
)

1 个答案:

答案 0 :(得分:1)

router未处理到状态 - 您应该可以在reducer.js文件中执行此操作:

reducer.js

...
import { routerStateReducer } from 'redux-router';

export default combineReducers({
  router: routerStateReducer,
...
})

这应该将您的所有路由器信息都置于状态,并使其可以访问您的connect函数:

component.js

@connect(
  state => ({
    profile: state.publicData.users[state.router.params.userId],
    error: state.publicData.profile.error,
    loading: state.publicData.profile.loading,
  }),
  { initializeWithKey }
)

此代码假定您拥有userId并且始终会,否则这将无法正常工作。

此外 - 根据您的更新 - ownProps也可以访问参数 -

@connect(
  (state, ownProps) => ({
    profile: state.publicData.users[ownProps.params.userId],
    error: state.publicData.profile.error,
    loading: state.publicData.profile.loading,
  }),
  { initializeWithKey }
)