首页 > 解决方案 > 从操作中访问 Redux 状态,我应该将 store 设为全局吗?

问题描述

我对 redux 很陌生,这是我的数据库的简化版本:

store: {
  userID: 1234,
  userData: { // fetch-ed from api
    foo,
    bar,
    ...
}

关于用户ID的变化,我想获取userData,我找到了一个名为redux-thunk的库,它可以使dispatch-es异步(我正在获取数据),但是对于获取URL,我需要来自商店的用户ID,而且我不知道如何直接从操作中访问它。

每次我像这样称呼它时,我应该将它传递给动作 dispatch(updateUser(store.getState().userID))吗?

标签: reactjsreduxredux-thunk

解决方案


我不确定我是否完全理解这个问题,但在我看来,您的思路是正确的,但可能需要重新考虑您的商店的结构。如果您有定义减速器的代码,那么在此处以及connect在组件的 props 中用于访问此数据的某处查看该代码会很有帮助。

如果没有,这是我的建议。

听起来您正在寻找能够显示用户配置文件并在它们之间切换的功能。在这种情况下,我建议您使用用户列表来构建您的商店,而不是使用被覆盖的单个用户对象。它看起来像这样:

{ 
  users: [{ id: '123', name: 'Hello' }, { id: '234', name: 'Goodbye' }],
  currentUserId: '123'
}

在这种情况下,要切换您在特定页面上显示的用户(或您的登录身份),您只需更改您在组件中选择的用户,而不是更新商店以user覆盖新用户。在 UI 元素更新当前用户而不更新 URL 的情况下(即,调用dispatch(updateCurrentUserId('234')),那么您的组件应该只根据以下内容从users商店中的键中选择用户:

const MyComponent = ({ user }) => (
  <div>User name is { user.name }</div>
);

const mapStateToProps = ({ users, currentUserId ) => ({
  user: users.find(u => u.id === currentUserId)
});

export default connect(mapStateToProps)(MyComponent);

这样,要切换代表哪个用户,您只需要currentUserId在商店中更改。

这假设您已经从 API 中获取了用户列表。如果您一次获取一个,您确实可以使用 redux thunk。我仍然建议将用户存储为列表,以便您可以轻松地在它们之间切换。在这种情况下,您的 thunk 会想要从商店中抓取用户(如果存在),或者如果不存在则获取它。像这样的东西:

// Alternately, you could pass *no* argument, and grab currentUserId
// from state like users below
const getUser = userId => (dispatch, getState) => {
  const localUsers = getState().users;
  const localUser = localUsers.find(u => u.id === userId);

  if (localUser) {
    // Because the user is in the store, we just need to point the frontend
    // to the right user.
    dispatch(updateCurrentUserId(userId));

  } else {
    // Fetch the user, add them to the store, and then point to them.
    fetch(`whatever.com/users/${userId}`)
      .then(response => {
         dispatch(addUser(response.data));
         dispatch(updateCurrentUserId(userId));
      }).catch(err => /* do something */);
  }
}

此 thunk 允许您根据用户是否存在于数据中进行有条件的异步行为。然而,与您的设计不同的是,您不会在新用户到来时覆盖当前用户。

请注意,您也可以在没有 的情况下执行此currentUserId操作,例如,只需从 URL 解析用户 ID。


推荐阅读