====== 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 з своїмі селекторами