Как лучше всего обновить состояние Redux в компонентах, которым нужны те же значения? - PullRequest
0 голосов
/ 29 мая 2020

У меня есть некоторые компоненты, которые могут отображаться вместе на странице или по отдельности, но им нужно одно и то же состояние (информация о заказе), то есть объект со всей информацией о заказе. Каждый компонент использует данные, которые ему нужны из этого состояния.

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

Проблема в том, что это состояние исходит от API, а его начальное состояние - неопределенный объект:

const initialState = {
    orderInfo: undefined,
};

Это потому, что он будет иметь свое состояние только тогда, когда клиент перейдет к исследованию порядок. Таким образом, всякий раз, когда клиент переходит к /dashboard/orders/:id/, компонент должен получить данные из API.

Первоначально я думал, что нужно проверить, не определено ли состояние или оно из другого идентификатора заказа. Если это так, отправьте действие для выборки из API:

useEffect(() => {
    // check if orderState contains order info and it's the same order
    if (!orderState.orderInfo || orderState.orderInfo._id !== id) {
        dispatch(getOrderInfo(id));
    }
    //eslint-disable-next-line
}, []);

Это работает, но я должен реализовать эту проверку для каждого компонента, потому что они могут отображаться в одиночку. Проблема в том, что когда на странице более 1 компонента, все они отправляют действие для получения данных из API в одно и то же время.

Как лучше всего сделать так, чтобы только один компонент отправлялся акция?

Заранее спасибо!

1 Ответ

0 голосов
/ 29 мая 2020

Думаю, есть два способа, которые могут вам подойти:

1: Пользовательские хуки

  • У вас может быть хук, который обрабатывает, что useEffect , и dispatch logi c, который также потребляет селектор данных в магазине. Что-то вроде:
function useOrder(foo, bar) {
  const dispatch = useDispatch()
  const order = useSelector(selectOrder)
  useEffect(() => {
    if (foo) {
      dispatch(bar)
    }
  }, [foo, bar])

 return order
}

А затем просто используйте его в своих компонентах:

const order = useOrder(foo, bar)

2.- Родительский контейнер.

  • Если все компоненты присутствуют одновременно, вероятно, должен быть глобальный контейнер, содержащий их все. Вы можете просто обработать там свой лог c и передать собственность. Для передачи реквизита у вас также есть 2 варианта:
    • Явная передача реквизита (поэтому просто передайте опору каждому вложенному компоненту, который в ней нуждается)
    • Использование контекста
const ctx = createContext({...})

<Provider context={ctx}>
 // Your component hierarchy
</Provider>

И затем внутри каждого из компонентов используйте хук useContext.

* Редактировать: В первом примере хука я передал реквизиты напрямую на крючок, но для вашего примера вы можете взять этот реквизит и из другого селектора.

...