Redux - удаление сущностей из родственного состояния - PullRequest
1 голос
/ 11 октября 2019

У меня есть состояние избыточности следующей формы, которое управляется в виде срезов с использованием combineReducers:

interface AppState {
  foos: Foo[];
  bars: Bar[];
  bazs: Baz[];
}

Они связаны следующим образом: Один Foo имеет много Bar. Один Bar имеет много Baz. Их структура выглядит следующим образом:

interface Foo {
  id: string;
  name: string;
}

interface Bar {
  id: string;
  name: string;
  fooId: string;
}

interface Baz {
  id: string;
  name: string;
  barId: string;
}

У меня есть обычные настройки thunks / actions для каждой части состояния, т.е. DELETE_FOO_REQUEST, DELETE_FOO_FAILURE DELETE_FOO_SUCCESS и другие параметры CRUD для каждой из сущностей.

Мой блок удаления foo выглядит следующим образом:

function deleteFoo(fooId) {
  return async (dispatch, getState) => {
    dispatch(deleteFooRequest());

    await api.deleteFoo(fooId);

    dispatch(deleteFooSuccess(fooId);
    // omitted error handling for brevity
  }
}

Дело в том: когда я удаляю Foo на моем API / бэкэнде, он также удаляет все связанные Bar s и Baz s . Теперь, как мне справиться с этим при использовании redux-thunk соглашений?

Создаю ли я больше действий в форме DELETE_BARS_FOR_FOO и отправляю их в том же блоке? Или я повторно использую DELETE_BAR_SUCCESS и использую его в цикле?

Вариант A

function deleteFoo(fooId) {
  return async (dispatch, getState) => {
    dispatch(deleteFooRequest());

    await api.deleteFoo(fooId);

    const barIds: string[] = selectBarsForFoo(fooId);

    dispatch(deleteFooSuccess(fooId);
    dispatch(deleteBarsForFoo(fooId);

    for (const barId of barIds) {
      dispatch(deleteBazForBar(barId));
    }

    // omitted error handling for brevity
  }
}

Вариант B

function deleteFoo(fooId) {
  return async (dispatch, getState) => {
    dispatch(deleteFooRequest());

    await api.deleteFoo(fooId);

    const barIds: string[] = selectBarsForFoo(fooId);

    dispatch(deleteFooSuccess(fooId);
    for (const barId of barIds) {
      dispatch(deleteBarSuccess(barId));
    }

    // followed by a similar loop for the bazs of each bar
    // omitted error handling for brevity
  }
}

В случае варианта B я повторно использую действие, означающеедля чего-то другого технически. В обоих действиях я выполняю цикл, который также влияет на производительность. Я, однако, использую реагирующий-редукс и могу использовать API batch(), так что не беспокойтесь.

Это только два моих варианта при использовании redux-thunk или есть улучшенный / обычныйспособ идти об этом?

1 Ответ

0 голосов
/ 11 октября 2019

Вместо того, чтобы усложнять ваши действия, можно просто решить эту проблему в вашем редукторе (как это предлагается в комментариях). Следующим способом вы все еще можете использовать combReducers, но иметь комбинированный редуктор, который получает {foo,bar,bas} в качестве состояния:

const fooBarBaz = combineReducers({
  foo:fooReducer,
  bar: barReducer,
  baz:bazReducer,
});
const combined = (state,action)=>{
  //handle foo remove success action, state is {foo,bar,baz}
}
export default function reducer(state,action){
  return combined(fooBarBaz(state,action),action)
}
...