Доступ состояния Redux из действий, я должен сделать магазин глобальным? - PullRequest
0 голосов
/ 25 октября 2018

Я совсем новичок в редуксе, вот упрощенная версия моего магазина:

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

Когда я меняю ID пользователя, я хочу автоматическое обновление для userData, я нашел для него библиотеку под названием redux-thunk,который может сделать dispatch-es асинхронным (я выбираю данные), но для получения URL мне нужен идентификатор пользователя из хранилища, и у меня нет доступа к нему напрямую из actions / updateUser.

Следуетя передаю это в действие каждый раз, когда я называю это как dispatch(updateUser(store.getState().userID))?

1 Ответ

0 голосов
/ 25 октября 2018

Я не уверен, что полностью понимаю вопрос, но мне кажется, что вы на правильном пути, но, возможно, захотите переосмыслить структуру вашего магазина.Если у вас есть код, в котором вы определяете свои редукторы, было бы полезно увидеть это здесь, а также где-нибудь, где вы используете connect для доступа к этим данным в подпорках компонента.

Если это не так, вот мои предложения.

Звучит так, будто вы ищете функциональность где-то на линии возможности отображать профили пользователей, переключаясь между ними.В этом случае я бы предложил структурировать ваш магазин с помощью списка пользователей, а не одного пользовательского объекта, который перезаписывается.Это выглядело бы примерно так:

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

В этом контексте, чтобы переключить пользователя, которого вы показываете на определенной странице (или кого вы вошли в систему), вы просто изменили быкакого пользователя вы выбираете в компоненте, вместо обновления хранилища для перезаписи user новым пользователем.В случае, когда элемент пользовательского интерфейса обновляет текущего пользователя без обновления 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Если вы выбираете их по одному, вы действительно можете использовать избыточный 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 */);
  }
}

Этот блок позволяет вам вести себя условно и асинхронно на основе того, существует ли ваш пользователь в данныхОднако, в отличие от вашего дизайна, вы не перезаписываете текущего пользователя при получении нового.

Обратите внимание, что вы также можете сделать это без currentUserId, вместо этого простопарсинг идентификатора пользователя из URL, например.

...