Redux

В React переменные (состояния) доступны только в пределах текущего компонента. Т.е. нельзя обращаться к состояним из одного компонента в другой.

Чтобы состояния были доступны в пределах всего React-приложения, используется Redux.

Для начала надо установить 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,
  },
})

Теперь в любом компоненте React можно использовать следующий код:

import { useSelector } from 'react-redux'

export default function ListItems() {

  const siteName = useSelector(state => state.siteName.value)

  return (
    <>
      <p>Имя: {siteName}</p>
      <p>Код компонента</p>
    </>
  );
};

Поменять состояние в React Redux

Сначала надо создать метод, который можно будет вызывать в любом месте кода компонента 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>
    </>
  );
};