#reactjs #redux #redux-toolkit
#reactjs #перенаправление #redux-toolkit
Вопрос:
В некоторых приложениях react / redux должен произойти переход к маршруту после отправки некоторого действия. В моем случае у меня именно такая ситуация. позвольте мне показать вам один редуктор фрагмента состояния.
nextStep: (state, action) => {
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep 1]) {
state.currentStep ;
} else {
state.currentTopNavStep ;
state.currentStep = 0;
}
if (action.payload.history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist amp;amp; valuesExist(state, fbObject)) ||
(gendersMatch amp;amp; gendersMatch(state))
) {
state.currentStep ;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
action.payload.history.push(newRoute.path);
}
}
В последней строке я хочу вставить новый маршрут в историю, который я получаю в качестве полезной нагрузки при отправке этого действия. Я хотел бы переместить логику внутри редуктора в промежуточное программное обеспечение. reduxToolkit предоставляет функцию createAsyncThunk. Я хочу получить что-то вроде этого:
const nextStep = createAsyncThunk(
'state/nextStep',
async (history, thunkAPI) => {
const { state } = thunkAPI.getState();
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep 1]) {
state.currentStep ;
} else {
state.currentTopNavStep ;
state.currentStep = 0;
}
if (history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist amp;amp; valuesExist(state, fbObject)) ||
(gendersMatch amp;amp; gendersMatch(state))
) {
state.currentStep ;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
const res = await history.push(newRoute.path);
return res; //this will be the action payload
}
}
);
А затем используйте это внутри extraReducers:
extraReducers: {
[nextStep.fullfilled]: (state, action) => {
//Here I face the problem, how to handle it in the reducer
return action.payload;
},
},
Кто-нибудь может мне помочь в этом случае
Ответ №1:
Дело в том, что промежуточное программное обеспечение не должно изменять состояние.
Вам действительно придется делать это отдельно друг от друга:
- редуктор изменяет состояние
- промежуточное программное обеспечение создает побочные эффекты
Кроме того, createAsyncThunk
здесь не тот инструмент. Цель cAT состоит в том, чтобы иметь thunk, который отправляет «ожидающее» действие, а затем «выполненное» или «отклоненное» действие. Похоже, они вам здесь вообще не нужны.
Вам либо нужно вручную написать обычный блок, который сначала отправляет действие, после этого отправка получает новое состояние, а затем выполняет побочный эффект, либо вам придется написать промежуточное программное обеспечение для этого самостоятельно (что также довольно просто, в документах есть примеры на этот счет).
Комментарии:
1. Спасибо за отзыв. Я искал везде, поскольку toolkit — это новый инструмент, случаев очень мало, и я не смог найти ничего полезного. Можете ли вы предоставить мне документы, в которых приведены примеры промежуточных программ, я не смог найти ничего хорошего. Заранее спасибо.
2. redux.js.org/tutorials/fundamentals/part-4-store#middleware RTK — это просто абстракция поверх простого redux, поэтому используйте его только там, где это имеет смысл —
createAsyncThunk
не делает недействительными «обычные» проги, и вся документация redux также остается в силе 😉3. Я получил все, что вы предложили сделать. Однако есть небольшая проблема. С самого начала я не могу получить доступ к истории маршрутизатора, где мне нужно протолкнуть новый маршрут. Я страдаю от этой проблемы весь день. Внутри обычного блока я хочу вставить новый URL-адрес в историю, а затем внутри редуктора просто внести изменения в состояние, но как мне получить саму историю.
4. Вы можете просто передать его в качестве аргумента создателю действия thunk
5. У меня все сработало, большое вам спасибо!!