Redux
В React переменные (состояния) доступны только в пределах текущего компонента. Т.е. нельзя обращаться к состояним из одного компонента в другой.
Чтобы состояния были доступны в пределах всего React-приложения, используется Redux.
Redux хранит состояния в отдельном файле, куда затем обращается React.
Для начала надо установить Redux.
npm install @reduxjs/toolkit react-redux
И создать файл «app/store.js» (также называют Redux Store).
// app/store.js
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {},
})
В данном файле будут храниться состояния, которые будут доступны во всём приложении React. Сейчас в этом файле пусто.
Теперь в основном файле надо подключить Redux через компонент <Provider>.
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
// Настройки для работы с Redux
import { Provider } from 'react-redux'
import store from './app/store'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
Создание состояния
Redux настроен, теперь надо создать состояние, которое будет доступно во всём приложении React.
Для этого надо создать файл features/siteName/siteNameSlice.js.
// features/siteName/siteNameSlice.js import { createSlice } from '@reduxjs/toolkit' export const siteNameSlice = createSlice({ name: 'siteName', // состояние "siteName" initialState: { value: "Приложение на Реакт", // значение по умолчанию }, }) export default siteNameSlice.reducer
И добавить файл в Redux Store (app/store.js).
// app/store.js import { configureStore } from '@reduxjs/toolkit' import siteNameReducer from '../features/siteName/siteNameSlice' export default configureStore({ reducer: { siteName: siteNameReducer, }, })
Теперь состояние доступно в любом компоненте. Обратиться к состоянию можно через метод useSelector().
import { useSelector } from 'react-redux' export default function ListItems() { const siteName = useSelector(state => state.siteName.value) return ( <> <p>Имя: {siteName}</p> <p>Код компонента</p> </> ); };
Поменять состояние в React Redux
Сначала надо создать метод (в Redux называется «Reducer»), который можно будет вызывать в любом месте кода компонента React.
// features/siteName/siteNameSlice.js import { createSlice } from '@reduxjs/toolkit' export const siteNameSlice = createSlice({ name: 'siteName', initialState: { value: "Приложение на Реакт", }, reducers: { setSiteName: (state, action) => { state.value = action.payload } }, }) export const { setSiteName } = siteNameSlice.actions export default siteNameSlice.reducer
Также есть функция createReducer(), но вместо неё рекомендуется использовать createSlice().
Теперь метод setSiteName можно вызывать в любом месте приложения React через dispatch().
import { useSelector, useDispatch } from 'react-redux' import { setSiteName } from './features/siteName/siteNameSlice' export default function ListItems() { const siteName = useSelector(state => state.siteName.value) const dispatch = useDispatch() return ( <> <p>Имя: {siteName}</p> <button onClick={() => dispatch(setSiteName("Новое значение"))}>Задать имя сайта</button> </> ); };
Работа с массивами в Redux
Преимущество Redux в том, что она облегчает работу с массивами.
// features/items/itemSlice.js
import { createSlice } from '@reduxjs/toolkit'
export const itemSlice = createSlice({
name: 'items',
initialState: {
items: [],
},
reducers: {
addItem: (state, action) => {
state.items.push({
id: action.payload.id,
name: action.payload.name,
active: true
});
},
removeItem: (state, action) => {
state.items = state.items.filter(item => item.id !== action.payload.id);
},
updateItem: (state, action) => {
const updatedItem = state.items.find(item => item.id === action.payload.id);
updatedItem.title = action.payload.title;
updatedItem.status = action.payload.status;
}
},
})
export const { addItem, removeItem, updateItem } = itemSlice.actions
export default itemSlice.reducer
Поддержать автора
Все статьи создаются и поддерживаются одним человеком,
если вам нравится контент, вы можете поддержать автора сайта
