Использование инструментария Redux в React
Вот краткий пример того, как реализовать redux-toolkit
в проекте, выполнив несколько простых шагов. В этом случае мы создали хранилище, используя несколько редукторов, по простому сценарию.
Установка redux-toolkit в наш проект
# NPM
npm install @reduxjs/toolkit
# Yarn
yarn add @reduxjs/toolkit
Создайте редукторы:
counterSlice:
этот код будет обновлять состояние‘counter’
.
import { createSlice } from "@reduxjs/toolkit";
export const counterSlice = createSlice({
name: "counter",
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload.amount;
},
},
});
// Actions: Functions created inside the reducer property above.
// Actions are used to update the state of the current Slice.
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
testSlice:
этот код обновит состояние‘test’
.
import { createSlice } from "@reduxjs/toolkit";
export const testSlice = createSlice({
name: "test",
initialState: {
plugin: "empty",
isWorking: true,
},
reducers: {
workingStatus: (state, action) => {
state.isWorking = action.payload;
},
plugin: (state, action) => {
state.plugin = action.payload;
},
},
});
export const {workingStatus,plugin} = testSlice.actions;
export default testSlice.reducer;
Создание магазина
На предыдущем шаге мы создали редукторы, которые теперь импортируются на этом этапе.
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./features/reducers/counterSlice";
import testReducer from "./features/counter/testSlice";
export default configureStore({
reducer: {
counter: counterReducer,
test: testReducer,
},
});
Настройка вашего проекта для использования Redux
Мы оборачиваем основной компонент нашего приложения поставщиком Redux, передавая наш магазин в качестве реквизита.
import store from "./store";
import { Provider } from "react-redux";
render(
<Provider store={store}>
<App />
</Provider>
)
Как получить доступ к магазину и управлять им
Чтобы продемонстрировать, как это работает, мы создали компонент под названием Counter, который изменяет хранилище, используя оба редуктора.
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { decrement, increment, incrementByAmount } from "../reducers/counterSlice";
import { plugin, workingStatus } from "../reducers/testSlice";
export function Counter() {
const count = useSelector((state) => state.counter.value);
const pluginName = useSelector((state) => state.test.plugin);
const isWorking = useSelector((state) => state.test.isWorking);
const dispatch = useDispatch();
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
<button
aria-label="Increment by Amount"
onClick={() => dispatch(incrementByAmount({ amount: 10 }))}
>
Increment by 10
</button>
<button
aria-label="Change Plugin Name"
onClick={() => dispatch(plugin("Pepe"))}
>
Change Plugin Name
</button>
<button
aria-label="Turn Off working"
onClick={() => dispatch(workingStatus(false))}
>
Turn Off Working
</button>
<h4>Is Working status:</h4>
<span>{String(isWorking)}</span>
<h4>Plugin Name</h4>
<span>{pluginName}</span>
</div>
</div>
);
}
Код поясняется фрагментами:
Импорт:
import { useSelector, useDispatch } from "react-redux";
import { decrement, increment, incrementByAmount } from "../reducers/counterSlice";
import { plugin, workingStatus } from "../reducers/testSlice";
useSelector:
мы извлекаем значения состояния, объявленного в'initialStatus: {}'
каждого среза.
useDispatch:
этот хук включает в себя функцию'dispatch'
, которая используется для обновления состояния каждого среза.
../reducers/Slice:
мы импортируем функции редуктора, которые включают действия по изменению состояния.
Получение фактического значения состояния
const count = useSelector((state) => state.counter.value);
const pluginName = useSelector((state) => state.test.plugin);
const isWorking = useSelector((state) => state.test.isWorking);
const dispatch = useDispatch();
- Используя
useSelector
, мы можем получить доступ к значению нашего состояния.
- Мы получаем функцию диспетчеризации от
useDispatch
для вызова действий по обновлению состояния.
Отображение и обновление состояния
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
dispatch(increment()): мы выполняем функцию increment()
, передавая ее в качестве параметра функции dispatch()
.
{count}: эта переменная связана с state.counter.value,
которое представляет текущее значение в хранилище, полученное при вызове useSelector((state) => state.counter.value)
.
Передайте значение в качестве параметра для обновления состояния.
<button
aria-label="Increment by Amount"
onClick={() => dispatch(incrementByAmount({ amount: 10 }))}
>
Increment by 10
</button>
- dispatch(actionFunction(parameter)): мы используем диспетчеризацию, предоставляя функцию действия с параметром. Для пояснения ниже приведено определение функции
ignoreByAmount()
, используемой в вышеупомянутом фрагменте кода.
incrementByAmount: (state, action) => {
state.value += action.payload.amount;
},
Это всего лишь простой пример, поэтому, пожалуйста, не стесняйтесь сообщать, если вы обнаружите какие-либо ошибки или упущения в этом документе.
Надеюсь эта статья оказалась полезной.
Спасибо!!