Для начала ответим на вопрос, для чего нам нужен Redux? 

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

Ключевым элементом любого компонента является его состояние или state. Это javascript-объект, включающий в себя ключи и значения требуемых свойств компонента. State не может быть изменен напрямую путем переопределения значений свойств или создания новых. Для этого в компонентах, созданных на основе классов, используется функция setState(<объект состояния>). Для компонентов, созданных на основе функций, используется хук useState, также позволяющий создавать и изменять свойства состояния компонента.

Управление состоянием это основа react, как и других аналогичных библиотек, таких как Vue или Angular. Любое изменение состояния приводит к "перезагрузке" компонента с новыми свойствами, соответствующими новому состоянию компонента.

Но есть некоторые трудности работы с состояниями компонентов. Дело в том, что state компонента существует изолированно от других компонентов. Есть возможности передачи состояний из одного компонента в другой. От родительского к дочернему компоненту свойства состояния могу передаваться через пропсы (props). 

<MyComponent propertyName="propertyValue" />

 Из дочернего компонента в родительский можно передать данные через функцию-коллбэк

import React from 'react';

class Parent extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            data: null
        }
    }

    handleCallback = (childData) =>{
        this.setState({data: childData})
    }

    render(){
        const {data} = this.state;
        return(
            <div>
                <Child parentCallback = {this.handleCallback}/>
                {data}
            </div>
        )
    }
}

class Child extends React.Component{
  
    onTrigger = (event) => {
        this.props.parentCallback("Data from child");
        event.preventDefault();
    }

    render(){
        return(
        <div>
            <form onSubmit = {this.onTrigger}>
                <input type = "submit" value = "Submit"/>
            </form>
        </div>
        )
    }
}

export default Parent;

 В данном примере callback-функция parentCallback передается через пропсы в дочерний компонент. Поскольку функция выполняется в  родительском компоненте, то аргумент этой функции передается в родительский компонент.

Все это довольно просто, но только если мы не имеем дело с десяткам, а то и сотнями компонентов. Отслеживание их взаимных отношений становится просто невозможно. 

Поэтому возникла идея создать новую сущность Store, такой общий state для всего приложения. Любой компонент приложения может обмениваться со Store данными почти также как со своим собственным стэйтом.

использование библиотеки Redux

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

Установка redux проста: "npm install redux" или "yarn add redux".

Затем создаем необходимые redux структуру и компоненты. Предлагается создать каталог store, который будет содержать нужные компоненты: экшены, редюсеры и другие.

Сначала создаем глобальное хранилище store:

const store=createStore(reducer)

 Функция createStore импортируется из библиотеки redux.