DevGang
Авторизоваться

Redux — мощный инструмент управления состоянием

Redux — мощный инструмент для управления состоянием в приложениях JavaScript, предлагающий предсказуемость и ясность в том, как данные вашего приложения изменяются с течением времени. Давайте разберем его определение и основные компоненты, чтобы понять его суть.

Совместимость приложений JavaScript

Redux не привязан к какой-либо конкретной среде JavaScript, такой как React; он универсален и может легко интегрироваться с различными фреймворками, такими как React, Angular, Vue, или даже использоваться независимо с простым ванильным JavaScript.

Предсказуемое управление состоянием

Redux предоставляет контейнер с предсказуемым состоянием. Это означает, что все переходы состояний в Redux управляемы и отслеживаются, обеспечивая ясность и контроль над развитием состояния вашего приложения.

Контейнер состояний

По своей сути Redux действует как контейнер состояний, хранящий все состояние вашего приложения. Сюда входят динамические данные, такие как информация о пользователе, сведения о продукте или любая другая соответствующая информация, необходимая для работы вашего приложения.

Три ключевые концепции Redux

  • Магазин: аналогично магазину в сценарии физического магазина, магазин Redux хранит все состояние приложения. Он служит центральным хранилищем ваших данных.
  • Reducer: подобно лавочнику, функция редуктора в Redux управляет переходами состояний на основе действий. Он слушает действия, отправляемые вашим приложением, и соответствующим образом изменяет состояние.
  • Действия: Действия представляют собой намерение изменить состояние. Точно так же, как покупатель поручает владельцу магазина выполнить определенную задачу, действия в Redux диктуют, какие изменения необходимо внести в состояние.

Три принципа Redux

  • Единое неизменяемое дерево состояний. Redux сохраняет состояние приложения в одном неизменяемом объекте. Такой централизованный подход упрощает управление состоянием и обеспечивает согласованность всего вашего приложения.
  • Действия как единственный источник изменения. В Redux единственный способ изменить состояние — это диспетчеризация действий. Эти действия описывают, что необходимо сделать, и служат основой для изменений состояния.
  • Чистые редукторы для преобразования состояния. Редюсеры в Redux — это чистые функции, отвечающие за преобразование состояния на основе отправленных действий. Они принимают текущее состояние и действие в качестве входных данных и возвращают новое состояние, не изменяя исходное состояние.

Основной поток приложения Redux

  • Инициализируйте хранилище Redux, в котором хранится состояние приложения.
  • Используйте getState() для доступа к текущему состоянию приложения.
  • Подпишитесь на магазин, чтобы получать обновления при изменении состояния.
  • Отправляйте действия в хранилище, чтобы инициировать переходы состояний на основе предопределенной логики.

Давайте создадим базовое приложение с использованием Redux, которое поможет лучше понять тему:

const initialState = {
    numOfCakes:10,
    numOfIcecreams:20
}

Здесь мы используем ванильный JavaScript для создания базового приложения, которое будет содержать начальное состояние с вышеупомянутыми данными. Теперь мы выполним переходы между состояниями, как это делается в приложении, использующем центральное хранилище.

Единственный способ изменить следующее состояние — создать действие, объект, описывающий, что произошло.

const BUY_CAKE = 'BUY_CAKE'; 
const BUY_ICECREAM = 'BUY_ICECREAM'; 

Выше приведены два действия для покупки торта и мороженого. Нам нужен объект действия со свойством type для отправки в редуктор. Объект действия необходим, поскольку действия часто содержат дополнительные данные, которые необходимо передать в редуктор. Каждый объект действия будет иметь свойство типа, представляющее действие, которое необходимо выполнить.

const buyCakeActionObj = {
     type:BUY_CAKE,
     info:'action to buy cake'
}

const buyIcecreamActionObj = {
     type:BUY_ICECREAM,
     info:'action to buy icecream'
}

Мы можем использовать эти объекты действий непосредственно в нашем приложении, но лучший способ — создать создателей действий, это функции, которые возвращают объект действия.

function buyCake(){
   return buyCakeActionObj;
}
function buyIcecream(){
   return buyIcecreamActionObj;
}

Теперь давайте, наконец, создадим редуктор для нашего приложения. Чтобы указать, как дерево состояний преобразуется действиями, мы пишем чистые редукторы. Чистые редукторы — это, по сути, чистые функции, которые принимают состояние и выполняемое действие в качестве параметров и возвращают обновленное состояние.

const reducer = (state = initialState, action) => {
    switch(action.type){
        case BUY_CAKE: return {
            ...state,
            numOfCakes: state.numOfCakes - 1
        }
        case BUY_ICECREAM: return {
            ...state,
            numOfIcecreams: state.numOfIcecreams - 1
        }
        default: return state
    }
}

Пришло время создать хранилище redux. Он хранит все состояние приложения.

const redux = require('redux');
const createStore = redux.createStore; // redux store

const store = createStore(reducer); // passing reducer to out store

Давайте воспользуемся методом getState() для доступа к состоянию нашего приложения. Он вернет текущее состояние приложения.

console.log("Initial State: " , store.getState());

Теперь нам нужно подписаться на магазин, чтобы получать обновления при каждом изменении состояния. Функция subscribe возвращает метод, который будет использоваться для отмены подписки и сохранения позже в приложении или при необходимости.

const unsubscribe = store.subscribe(() => console.log('Updated state: ' ,store.getState()));

На последнем этапе, чтобы выполнить переходы между состояниями, нам нужно отправить действия в хранилище.

store.dispatch(buyCake()); //  dispatching the action to reducers
store.dispatch(buyIcecream());
unsubscribe(); // unsubscribed to the store

Теперь вы можете протестировать покупку приложения, вызвав методы buyCake() и buyIcecream(), и увидеть, как меняется состояние, и обновленное состояние будет регистрироваться на консоли.

Асинхронные действия

Асинхронные действия используются для выполнения асинхронных вызовов API, получения данных из конечной точки и интеграции их в наше приложение. Они облегчают получение информации из внешнего API неблокирующим способом, обеспечивая плавную интеграцию с логикой и потоком приложения.

Теперь мы разработаем приложение, которое извлекает пользователей из конечной точки API и сохраняет данные в магазине Redux.

Создайте файл index.js или файл с любым именем по вашему выбору и приступайте к написанию нашего приложения шаг за шагом.

const initalState = {
    loading:true,
    users:[],
    error:''
}

Создайте исходное состояние, как указано выше. Здесь у нас есть флаг загрузки, который уведомляет о том, что данные в данный момент извлекаются, о пользователях, которые содержат массив извлеченных пользователей, и об ошибке, которая содержит любое сообщение об ошибке на случай возникновения каких-либо ошибок.

Теперь мы определим наши действия. В нашем приложении будет три типа действий.

FETCH_USERS_REQUEST — Получить список пользователей

FETCH_USERS_SUCCESS — получено успешно.

FETCH_USERS_FAILURE — Ошибка при получении пользователей.

// actions
const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST'; // to make request to API.
const FETCH_USERS_SUCCESS = 'FETCH_USERS_SUCCESS'; // success response from API.
const FETCH_USERS_FAILURE = 'FETCH_USERS_FAILURE'; // failure response from API.
// action creators
const fetchUsersRequest = () => {
    return {
        type:FETCH_USERS_REQUEST
    }
}

const fetchUsersSuccess = (users) => {
    return {
        type:FETCH_USERS_SUCCESS,
        payload:users
    }
}

const fetchUsersFailure = (error) => {
    return {
        type:FETCH_USERS_FAILURE,
        payload:error
    }
}

Определение редуктора для нашего приложения.

// reducer
const reducer = (state = initalState,action) => {
    switch(action.type){
        case FETCH_USERS_REQUEST:
            return {
                ...state,
                loading:true
            }
        case FETCH_USERS_SUCCESS:
            return {
                loading:false,
                users:action.payload,
                error:''
            }   
        case FETCH_USERS_FAILURE:
            return {
                loading:false,
                users:[],
                error:action.payload
            }     
    }

}

Redux Thunk

Промежуточное программное обеспечение Redux Thunk позволяет вам писать создатели действий, которые возвращают функцию вместо действия. Thunk можно использовать для задержки отправки действия или для отправки только при выполнении определенного условия. Внутренняя функция получает в качестве параметров методы хранилища send и getState.

const fetchUsers = () => {
    return async (dispatch) => {
          dispatch(fetchUsersRequest());
          try {
            const res = await axios.get('https://jsonplaceholder.typicode.com/users');
            console.log("Data Fetched!!!");
            const users = res.data;
            console.log("Users:",users);
            dispatch(fetchUsersSuccess(users));
          } catch (error) {
            dispatch(fetchUsersFailure(error.message));
          }

    }
}

Теперь нам нужно создать хранилище Redux.

const redux = require('redux');
const createStore = redux.createStore;
const applyMiddleware = redux.applyMiddleware;
const thunk = require('redux-thunk').default;

//! store
const store = createStore(reducer,applyMiddleware(thunk));
const unsubscribe = store.subscribe(() => console.log(store.getState()));
store.dispatch(fetchUsers());
unsubscribe();

Теперь, если мы запустим следующий фрагмент кода, будет отправлено действие fetchUsers(), которое извлекает пользователей из конечной точки API через axios.

Заключение

Redux предлагает мощное решение по управлению состоянием для сложных приложений JavaScript, обеспечивающее предсказуемый и централизованный поток данных, который повышает удобство обслуживания, масштабируемость и производительность разработчиков.

Источник

#JavaScript #Redux
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу