====== Redux Toolkit - Керування стейтами (новий правильний варіант) ======
[[https://redux-toolkit.js.org/|redux-toolkit]] це офіційна бібліотека для ефективної розробки з використанням Redux, яка призначена для стандартизації та спрощення написання логіки Redux.
===== Встановлення =====
Використовуючи Redux Toolkit, немає необхідності додавати в проект пакет redux, крім випадків, коли вам необхідна функція combineReducers(). Достатньо встановити @reduxjs/toolkit для написання логіки Redux та react-redux для зв'язку стора з компонентами.
npm install @reduxjs/toolkit
===== Створюємо структуру файлів (приклад) =====
* /сomponents/redux/
* store.jsx - сховище верхнього рівня що буде керувати усіма підлеглими
* contactsSlice.jsx - підлегле сховище що керує значенніми (стейтами) повязаними з контактами
* filtersSlice.jsx - підлегле сховище що керує стейтами повязаними з фільтрами
===== Конфігурація головного сховища (store.jsx) =====
import { configureStore } from "@reduxjs/toolkit";
import { contactsReducer } from "./contactsSlice"; //Redux Toolkit - імпортуємо слайс контактів
import { filtersReducer } from "./filtersSlice"; //Redux Toolkit - імпортуємо слайс фільтрів
//persist - імопртуємо необхідні бібліотеки persist redux. З цим не розбирємось - просто копіюємо
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from "redux-persist";
import storage from "redux-persist/lib/storage";
//persist
//persist - вказуємо які редюсери нам потрібно зберегти в локальному сховищі
const contactsPeristConfig = {
key: "contactsitems",
storage,
whitelist: ["items"], // зберігаємо лише властивість items з головного сховища у локальному сховищі (білий список)
};
//persist
//Redux Toolkit - єкспортуємо головне сховище store
export const store = configureStore({
reducer: {
contacts: persistReducer(contactsPeristConfig, contactsReducer), //redux-persist - додаємо до головного сховища збережені дані в локальному сховищі
filters: filtersReducer
},
//persist - конфігурація middleware для redux-persist. З цим не розбирємось - просто копіюємо
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
//persist
});
//persist - єкспортуємо store з redux-persist
export const persistor = persistStore(store);
//persist
===== Налаштовуємо підлегле сховище (слайс) (приклад contactsSlice.jsx)=====
Краще викорситовувати цей метод бо одночасно тсворить і редюсер і єкшен.
Тут вже не треба притримуватись то іммутабельного принципу зміни бо усе одлно всередині він буде перетворений у іммутабельний
import { createSlice } from "@reduxjs/toolkit";
//Первинне значення для слайса
const INITIAL_STATE = {
items: []
};
//створення слайса з значенням і методами
const contactsSlice = createSlice({
name: "contacts",
initialState: INITIAL_STATE,
reducers: {
addContact(state, action) {
state.items.push(action.payload);
},
deleteContact(state, action) {
state.items = state.items.filter((contact) => contact.id !== action.payload);
},
},
});
export const { addContact, deleteContact } = contactsSlice.actions; // деструктуризація і імпортування методів з слайсу
export const contactsReducer = contactsSlice.reducer; // імпортування самого слайсу
====== Persistor (синхронізація значень між станами та локальним сховищем) з Redux Toolkit======
[[persistor_-_sinxronizacija_staniv_mizh_redux_i_lokalnim_sxovischem|Redux Persist - синхронізація станів між redux і локальним сховищем]]
====== СreateAsyncThunk (асинхронні запити) з Redux Toolkit======
[[createasyncthunk_-_asinxronni_zapiti_v_redux_toolkit|createAsyncThunk - асинхронні запити в Redux Toolkit]]
====== useSelector (Селектори) в Redux Toolkit ======
Щоб отримати дані зі стору, компоненти повинні підписатися на необхідні їм частини стану Redux. Для цього у бібліотеці React Redux є хук useSelector(selector). Аргументом він приймає функцію, яка оголошує один параметр state - весь об'єкт стану Redux, який буде автоматично переданий функції хуком useSelector. Ця функція називається селектором і повинна повернути тільки ту частину стану, яка необхідна компоненту.
Селектори це функції, які інкапсулюють у собі читання значень із стану Redux. У найпростішому вигляді вони очікують на поточний стан Redux та повертають необхідну його частину.
* **Варіант 1 - в коді модуля**
// Імпортуємо хук
import { useSelector } from "react-redux";
const MyComponent = () => {
// Отримуємо необхідну частину стану
const value = useSelector(state => state.some.value);
};
* **Варіант 2 - селектори в файлах**
// src/redux/selectors.js
export const getTasks = state => state.tasks.items;
export const getIsLoading = state => state.tasks.isLoading;
export const getError = state => state.tasks.error;
export const getStatusFilter = state => state.filters.status;
а потім імпортуємо його в в основний код і проміняємо
import {selectTimer} from "..//redux/timer/selector.js
const timer = useSelector (selectTimer);
Правилами гарного тону є у папці кожного слайсу класти файл selectors.js з своїмі селекторами