- Створити стор (редюсери + початковий стан)
- Створити інтерфейс (компоненти) і підписатися на стан
- Оголосити необхідні екшени
- Відправити екшен
- Обробити екшен в редюсері
- Оголосити операцію за допомогою
createAsyncThunk
(див. файл contactOps.js) - Передати ій 2 аргументи, базовий тип екшену (рядок) та асинхронну функцію
- Зробити
dispatch
операціі у КОМПОНЕНТІ при подіі/ефекті і перевірити, чи спрацьовують екшени - Якщо все ок - додати HTTP запит в асинхронну функцію операціі і повернути дані (див. файл contactOps.js)
- Не забудь додати 2й аргумент
thunkAPI
, який потрібен для коректного відпрацювання помилки запиту. Для цього в частиніcatch
прописати:return thunkAPI.rejectWithValue();
- Обробити екшени операціі (pending, fulfilled, rejected) у слайсі у
властивості
extraReducers
->builder.addCase()
(див. файл contactsSlice.js)
- скорочено:
export const changeFilter = createAction("contacts/changeFilter");
Пояснення: Функція createAction приймає рядок - type екшену. При виклику екшену як фунції передане їй значення потрапляє у payload. Нпр.: changeFilter(query) це екшен
const changeFilter = {
type: "filters/changeFilter",
payload: query,
};
- розширено: По type екшену редюсер розрізняє який саме екшен відбувся. A payload - це значення, яке передається при виклику (діспатчі) екшену
export const changeFilter = query => {
return {
type: "filters/changeFilter",
payload: query,
};
};
Тут contacts та filters - частини стану стора (слайси). А addContact, deleteContact та changeFilter - екшени
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case "contacts/addContact": {
return {
...state,
contacts: {
...state.contacts,
items: [...state.contacts.items, action.payload],
},
};
}
case "contacts/deleteContact": {
return {
...state,
contacts: {
...state.contacts,
items: state.contacts.items.filter(
task => task.id !== action.payload
),
},
};
}
case "filters/changeFilter": {
return {
...state,
filters: {
...state.filters,
name: action.payload,
},
};
}
default:
return state;
}
};
export const store = configureStore({
reducer: rootReducer,
});
Див. коментарі внизу (файл contactsSlice.js)