Установка Редукса
Итак, начнем. Прежде всего, установите Redux и React-Redux, выполнив следующую команду:
npm install redux react-redux
В качестве альтернативы, если вы используете пряжу:
yarn add redux react-redux
Вот и все! Вы установили библиотеку Redux и привязки React-Redux в свой пример проекта React. Теперь мы можем приступить к настройке нашего примера магазина Redux и подключению ваших компонентов React.
Настройка магазина Redux
Представьте, что вы строите дом. Магазин Redux — это основа, на которой все скрепляется. Очень важно правильно настроить его, чтобы обеспечить стабильность вашего приложения. Начнем с создания простого магазина Redux:
import { createStore } from "redux";
import rootReducer from "./reducers";const store = createStore(rootReducer);
export default store;
В этом примере мы импортируем createStore
функция из Redux и rootReducer
от наших редукторов. Затем мы создаем магазин, используя createStore
функция, переходящая в rootReducer
.
Подключение компонентов к хранилищу
Теперь, когда наш магазин готов, нам нужно подключить его к нашим компонентам React. Это соединение похоже на мост, позволяющий компонентам получать доступ и изменять состояние приложения. Подключим простой Counter
Компонент в нашем магазине:
import React from "react";
import { connect } from "react-redux";
import { increment, decrement } from "./actions";const Counter = ({ count, increment, decrement }) => (
Counter: {count}
);const mapStateToProps = (state) => ({ count: state.count });
const mapDispatchToProps = { increment, decrement };
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
В этом примере мы используем connect
функция от react-redux
подключить наш Counter
компонент в магазин Redux. mapStateToProps
Функция определяет, как состояние из хранилища сопоставляется с реквизитами компонента. mapDispatchToProps
object сопоставляет создателей действий реквизитам компонента.
Реализация действий и редукторов
Действия и редукторы работают в тандеме, как партнеры по танцу, для управления состоянием нашего приложения. Давайте определим простой создатель действия и редьюсер для обработки увеличения и уменьшения нашего счетчика:
// actions.js
export const increment = () => ({ type: "INCREMENT" });
export const decrement = () => ({ type: "DECREMENT" });// reducers.js
const initialState = { count: 0 };
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENT":
return { ...state, count: state.count + 1 };
case "DECREMENT":
return { ...state, count: state.count - 1 };
default:
return state;
}
};
export default rootReducer;
В этом примере мы определяем двух простых создателей действий, increment
и decrement
. В редюсере мы обрабатываем эти действия, соответствующим образом обновляя состояние.
Применение ПО промежуточного слоя
Промежуточное программное обеспечение позволяет нам расширять возможности Redux, например, добавлять сверхспособности в наш магазин. Установите Redux-Thunk:
npm install redux-thunk
Применим популярные redux-thunk
промежуточное ПО для обработки асинхронных действий:
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;
Здесь мы импортируем applyMiddleware
функция из Redux и thunk
от redux-thunk
. Затем мы применяем промежуточное ПО при создании магазина.
Оптимизация производительности
Теперь, когда наш магазин Redux запущен и работает, нам нужно обеспечить оптимальную производительность. Мы можем использовать React.memo
функции и useMemo
hook для запоминания наших компонентов и предотвращения ненужного повторного рендеринга, что может помочь улучшить общую производительность нашего приложения. Давайте оптимизируем нашу Counter
компонент:
import React, { useCallback } from "react";
import { connect } from "react-redux";
import { increment, decrement } from "./actions";const Counter = React.memo(({ count, increment, decrement }) => {
const handleIncrement = useCallback(() => increment(), [increment]);
const handleDecrement = useCallback(() => decrement(), [decrement]);
return (
Counter: {count}
);
});const mapStateToProps = (state) => ({ count: state.count });
const mapDispatchToProps = { increment, decrement };
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
В этом примере мы обертываем наш Counter
компонент с React.memo
, что гарантирует повторную визуализацию компонента только при изменении его свойств. Мы также используем useCallback
крючок, чтобы запомнить handleIncrement
и handleDecrement
функции. Эта оптимизация предотвращает ненужный повторный рендеринг и обеспечивает бесперебойную работу нашего приложения.
Обработка асинхронных действий с помощью Redux-Thunk
Предположим, вы работаете над простым погодным приложением, которое извлекает данные о погоде из API. В этом случае вам потребуется обрабатывать асинхронные действия для запроса и обновления состояния на основе ответа API. Для этого мы будем использовать промежуточное ПО Redux-Thunk.
Создать новый генератор действий fetchWeather
в actions/weatherActions.js
:
import axios from "axios";export const FETCH_WEATHER_REQUEST = "FETCH_WEATHER_REQUEST";
export const FETCH_WEATHER_SUCCESS = "FETCH_WEATHER_SUCCESS";
export const FETCH_WEATHER_FAILURE = "FETCH_WEATHER_FAILURE";
export const fetchWeatherRequest = () => ({
type: FETCH_WEATHER_REQUEST,
});
export const fetchWeatherSuccess = (weather) => ({
type: FETCH_WEATHER_SUCCESS,
payload: weather,
});
export const fetchWeatherFailure = (error) => ({
type: FETCH_WEATHER_FAILURE,
payload: error,
});
export const fetchWeather = (city) => {
return (dispatch) => {
dispatch(fetchWeatherRequest());
axios
.get(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`)
.then((response) => {
dispatch(fetchWeatherSuccess(response.data));
})
.catch((error) => {
dispatch(fetchWeatherFailure(error.message));
});
};
};
Обновите свой store.js
чтобы включить новое промежуточное ПО:
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";const store = createStore(rootReducer, applyMiddleware(thunk));
export default store;
Использование combReducers для управления несколькими редьюсерами
Предположим, вашему приложению требуется отдельный редьюсер для аутентификации пользователя. Вы можете использовать combineReducers
Функция из Redux для объединения нескольких редюсеров в один.
Создайте новый редуктор в reducers/authReducer.js
:
const initialState = {
isLoggedIn: false,
user: null,
};const authReducer = (state = initialState, action) => {
switch (action.type) {
case "LOGIN_SUCCESS":
return { ...state, isLoggedIn: true, user: action.payload };
case "LOGOUT":
return { ...state, isLoggedIn: false, user: null };
default:
return state;
}
};
export default authReducer;
Теперь обновите свой reducers/index.js
использовать combineReducers
:
import { combineReducers } from "redux";
import weatherReducer from "./weatherReducer";
import authReducer from "./authReducer";const rootReducer = combineReducers({
weather: weatherReducer,
auth: authReducer,
});
export default rootReducer;
Вложенное состояние и хук useSelector
Вместо использования connect
вы можете использовать useSelector
крючок из react-redux
для доступа к состоянию в функциональных компонентах.
Измените свой Weather
компонент для использования useSelector
крюк:
import React from "react";
import { useSelector } from "react-redux";const Weather = () => {
const weather = useSelector((state) => state.weather.weatherData);
const isLoading = useSelector((state) => state.weather.isLoading);
return (
{isLoading ? (
Loading...
) : (
{weather.name}
Temperature: {weather.main.temp}°F
)}
);
};export default Weather
Хук useDispatch и диспетчеризация действий
Чтобы отправить действия из ваших функциональных компонентов, вы можете использовать useDispatch
крючок из react-redux
. Вот как вы можете изменить Weather
компонент, чтобы включить кнопку, которая запускает fetchWeather
действие:
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchWeather } from "../actions/weatherActions";const Weather = () => {
const weather = useSelector((state) => state.weather.weatherData);
const isLoading = useSelector((state) => state.weather.isLoading);
const dispatch = useDispatch();
const [city, setCity] = useState("");
const handleCityChange = (e) => {
setCity(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
dispatch(fetchWeather(city));
};
return (
{isLoading ? (
Loading...
) : (
{weather && (
<>
{weather.name}
Temperature: {weather.main.temp}°F
>
)}
)}
);
};export default Weather;
Интеграция Redux DevTools для упрощения отладки:
Чтобы упростить отладку вашего состояния Redux, вы можете интегрировать свое приложение с Redux DevTools. Вот как вы можете обновить свой store.js
чтобы включить Redux DevTools:
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancers(applyMiddleware(thunk)));
export default store;
Благодаря этим примерам у вас должно быть более полное представление о том, как использовать Redux в приложении React.
2023-06-21 16:51:12
1687556028
#Освоение #Redux #сбалансированный #анализ #для #разработчиков #React