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

Redux - это контейнер с предсказуемым состоянием для приложений JavaScript. Он помогает вам писать приложения, которые ведут себя согласованно, работают в разных средах (клиентских, серверных и собственных) и легко тестируются.

Redux в приложениях React стал отраслевым стандартом для создания масштабируемых приложений React.

Посмотрите это видео Я преподаю эту статью на примере в видео ниже

Почему Redux?

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

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

Принципы Redux

  • Магазин нельзя изменить напрямую, Магазин можно изменить, только выполнив действие. Каждое действие, например отправка формы, вызывает действие. например, пользователь может нажать кнопку, чтобы отправить контактную форму, которая вызовет действие SUBMIT_CONTACT_FORM.
  • Изменения состояния и обрабатываются чистыми функциями, называемыми редукторами. Редукторы обновляют состояние.

Редуктор - это функция, которая принимает текущее состояние и действие и возвращает новое состояние. Каждое действие / операция обрабатывается одним или несколькими редукторами, которые обновляют одно хранилище. reducer получает текущее состояние и действие, он содержит переключатель if для проверки типа действия и возвращает новое состояние. после того, как редуктор возвращает новое состояние, хранилище обновляется. React повторно визуализирует компонент, использующий данные.

1. Действие

Redux - это структура управления состоянием, обновление состояния - одна из ее основных задач. В Redux все обновления состояния запускаются отправкой действий.

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

const action = {
    type: ‘LOGIN’
};

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

const action = {
    type: ‘LOGIN’
};
// action Creator
const actionCreator = () => {
   return action; 
}

можно резюмировать и записать как создатель действий

const actionCreator = () => {
   return { type: ‘LOGIN’ } 
}

еще один пример действия Оцените фильм и содержит полезную нагрузку

rateMovie(rating) {
    return { type: RATE_MOVIE, payload: rating }
}

Вы можете передавать сериализуемые в JSON вещи. Вы не должны передавать функции. rateMovie - создатель экшенов.

Отправка события действия

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

store.dispatch(actionCreator());
store.dispatch({ type: 'LOGIN' });

Пример: здесь мы отправляем создателя действия входа в магазин

const store = Redux.createStore(
   (state = { login: false }) => state
);
const loginAction = () => { 
   return { type: 'LOGIN' }
};

// Dispatch the action 
store.dispatch(loginAction());

2. Редукторы

Редуктор - это функция, которая принимает текущее состояние и действие и возвращает новое состояние. Каждое действие / операция обрабатывается одним или несколькими редукторами, которые обновляют одно хранилище.

Обратите внимание, что reducer никогда не вызывает конечную точку API, и у него никогда не бывает скрытых сюрпризов. Редуктор - это просто чистая функция, которая принимает состояние и действие, а затем возвращает ТОЛЬКО новое состояние.

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

function myReducer(state = initialState, action){
    // Return new state based on action passed
}

Пример: счетчик приращения дескриптора

function myReducer(state, action){
    switch(action.type){
        case "INCREMENT_COUNTER":
            state.counter++;
            return state;
        default:
            return state;
    }
}

Примечание: (Вы не можете этого сделать, вы мутируете состояние Исправьте) creating the new object by copying the existing state. and on that new object increment the counter.

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

function myReducer(state, action){
    switch(action.type){
        case "INCREMENT_COUNTER":
            return {...state, counter: state.counter + 1};
        default:
            return state;
    }
}

Редукторы должны возвращать обновленную копию состояния. Redux будет использовать эту копию для обновления магазина.

const defaultState = {
   login: false
};
// Reducer
const reducer = (state = defaultState, action) => {
   if (action.type === ‘LOGIN’) {
       return {…state, login: true}
   } else {
       return {…state, login: false}
   }
};
const store = Redux.createStore(reducer);
const loginAction = () => {
     return { type: ‘LOGIN’ }
};

Обработка нескольких действий в одном редукторе с помощью оператора switch

const defaultState = {
  authenticated: false
};
const authReducer = (state = defaultState, action) => {  switch(action.type){
 case ‘LOGIN’:
       return {…state, authenticated : true}
 case ‘LOGOUT’:
       return {…state, authenticated : false} 
 default:
       return state
}
};
const store = Redux.createStore(authReducer);
const loginUser = () => {
   return { type: ‘LOGIN’ } 
};
const logoutUser = () => { 
   return { type: ‘LOGOUT’ }
};

Удалите Волшебные строки. назначить типы действий как константы только для чтения, а затем ссылаться на эти константы везде, где они используются. Итак, мы реорганизуем приведенный выше код, добавив LOGIN и LOGOUTas const.

const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';
const defaultState = {
  authenticated: false
};
const authReducer = (state = defaultState, action) => {  switch(action.type){
 case LOGIN:
       return {…state, authenticated : true}
 case LOGOUT:
       return {…state, authenticated : false} 
 default:
       return state
}
};
const store = Redux.createStore(authReducer);
const loginUser = () => {
   return { type: LOGIN } 
};
const logoutUser = () => { 
   return { type: LOGOUT }
};

3. Магазин

Redux store - это объект, который содержит и управляет приложением state. Для объекта Redux существует метод createStore(), который вы используете для создания Redux store. Этот метод принимает функцию reducer в качестве обязательного аргумента.

const reducer = (state = 5) => {
   return state;
}
let store = Redux.createStore(reducer)

redux подчиняются принципу единой ответственности.

Store = ›хранить данные, и Reducer заботится об изменении состояний.

Объект хранилища Redux предоставляет несколько методов, которые позволяют вам взаимодействовать с ним.

Магазин может

  • store.dispatch (действие)
  • store.subscribe (действие)
  • store.getState ()
  • replaceReducer (nextReducer)

The only way to change a store by dispatching an action. Store cannot be changed directly. Actions are handled by reducers.

Например, вы можете получить текущий state, хранящийся в объекте хранилища Redux, с помощью метода getState().

const store = Redux.createStore(
    (state=5) => state
);
let currentState = store.getState();

Зарегистрируйте прослушиватель магазина

Другой метод, к которому у вас есть доступ к объекту Redux store, - это store.subscribe(). Это позволяет вам подписывать функции слушателя на хранилище, которые вызываются всякий раз, когда действие отправляется в хранилище.

const ADD = 'ADD';
const reducer = (state = 0, action) => {
switch(action.type) {
 case ADD:
   return state + 1;
 default:
   return state;
 }
};
const store = Redux.createStore(reducer);
let count = 0;
store.subscribe( () => {
    count++;
 }
);
store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);
store.dispatch({type: ADD});
console.log(count);

Он будет подписываться каждый раз при отправке действия и печатать счетчик 1, 2, 3.

Одно хранилище и несколько редукторов

Вы можете управлять срезами изменений состояния с помощью нескольких редукторов в redux. Все редукторы вызываются при отправке действия. Оператор switch внутри каждого редуктора смотрит на тип действия, чтобы определить, нужно ли ему что-нибудь делать. вот почему все редукторы должны возвращать нетронутое состояние по умолчанию. Таким образом, ни один регистр не соответствует переданному действию, возвращается существующее состояние.

Например, у меня есть три редуктора LoadStatus, Courses и Authors, только редуктор, который обрабатывает тип действия DELETE_COURSE, будет что-либо делать. Остальные просто вернут переданное им состояние. Каждый редуктор обрабатывает свой фрагмент состояния. Фактически, каждому редуктору передается только его часть состояния. поэтому он может получить доступ только к той части состояния, которой он управляет.

Таким образом, хотя существует только одно хранилище для redux, создание нескольких редукторов позволяет обрабатывать изменения в разных частях хранилища изолированно. все редукторы вместе образуют картину того, что есть в магазине.

«Напишите независимые небольшие функции-редукторы, которые будут отвечать за обновления определенного фрагмента состояния. Мы называем этот паттерн «композиция редуктора». Данное действие может выполняться всеми, некоторыми или никем из них ».

Каждое действие может обрабатываться несколькими редукторами. Каждый редуктор может обрабатывать несколько действий.

Отметьте следующий проект: Скоро я добавлю больше к этой статье.

const rootReducer = Redux.combineReducers({
  auth: authenticationReducer,
  notes: notesReducer
});

пример

const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const counterReducer = (state = 0, action) => {
switch(action.type) {
    case INCREMENT:
         return state + 1;
    case DECREMENT:
         return state - 1;
    default:
         return state;
 }
};
const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';
const authReducer = (state = {authenticated: false}, action) => {
 switch(action.type) {
     case LOGIN:
           return { authenticated: true }
     case LOGOUT:
           return { authenticated: false }
     default:
           return state;
 }
};
const rootReducer = Redux.combineReducers({
      auth: authReducer,
      count: counterReducer
})
const store = Redux.createStore(rootReducer);

Отправить данные о действиях в магазин

Подписывайтесь на меня в Instagram 📷 и Linkedin 💬 .