Redux React Native: как правильно вызывать несколько действий из разных редукторов

В моем приложении response native / redux я хотел бы отправить несколько действий.

Я обрабатываю список элементов в своем приложении. С одним редуктором я поддерживаю коллекции как словарь {CollectionId: [ElementId1, ElementId2, ElementId3]. А в другом редукторе я поддерживаю словарь Elements {ElementId: {ElementName, ElementData, ...}}. Таким образом данные будут максимально нормализованы.

Теперь, если я хочу удалить все элементы из определенного collectionId, как мне отправить следующие два действия:

batch(() => {
    dispatch(deleteCollection(collectionId)) // removes the collection from the first reducer dictionary
    dispatch(deleteElements(Array<ElementIds>)) // removes all Elements 
}),

Однако я не знаю заранее массив, у меня есть доступ только к collectionId. Это похоже на то, что первая отправка должна возвращать идентификаторы элементов, чтобы я знал, что нужно удалить в моем втором редукторе.

Мои вопросы: можно ли вернуть какое-то значение из действия редуктора? Могу ли я вызвать второе действие из первого? Должен ли я писать всю свою логику вне редукторов и использовать редукторы только как способ изменения состояния, но вычислять, как оно будет изменено изнутри компонента или чего-то еще?


person Waroulolz    schedule 03.07.2020    source источник
comment
Должны ли быть два действия? Почему бы вам просто не использовать одно действие DELETE_COLLECTION, которое удаляет коллекцию, а также удаляет элементы этой коллекции? Я имею в виду, есть ли случай, когда вам нужно удалить коллекцию и сохранить ее элементы?   -  person Hani    schedule 03.07.2020


Ответы (1)


Для начала нужно получить arrayOfElementIds. Также вам нужно сначала удалить Elements, а затем коллекцию.

вариант 1 - при условии, что deleteElements и deleteCollection асинхронны

// option 1 - assuming `deleteElements` and `deleteCollection` are asynchronous
const batch = () => (dispatch) => {
  dispatch(deleteElements(collectionId)); // removes all Elements
};

const deleteElements = (collectionId) => async (thunk) => {
  // make api call and delete
  const arrayOfElementIds = await getCollection(collectionId);
  await apiService.post("/url", arrayOfElementIds);
  dispatch(deleteCollection(collectionId)); // removes the collection from the first reducer dictionary
};

const getCollection = (collectionId) => { // write a little helper to get the array of ids
  // make an api call or dispatch an action or something like that and obtain array of element Ids
  return new Promise((res, rej) => {
    res(["array of ids..."]);
  });
};

вариант 2 - получить arrayOfElementIds из магазина

// option 2 - get the arrayOfElementIds from the store using useSelector or mapStateToProps
const batch = () => {
  const arrayOfElementIds = useSelector(
    // get the arrayOfElementIds from the store
    (state) => state.ElementId.arrayOfElementIds
  );
  dispatch(deleteElements(arrayOfElementIds)); // removes all Elements
  dispatch(deleteCollection(collectionId)); // removes the collection from the first reducer dictionary
};
person gdh    schedule 03.07.2020
comment
Мне нравятся идеи, и они, очевидно, подходят для чего-то вроде удаления, верно. Но теперь, если я хочу реализовать что-то вроде RemoveDuplicates (), это не поможет. Если я хочу удалить дубликаты, мне нужно найти повторяющиеся элементы, получить их идентификаторы, удалить их, а затем передать эти идентификаторы редуктору коллекции и удалить эти идентификаторы оттуда. - person Waroulolz; 03.07.2020