frost18
@frost18
Программист PHP

Что такое Redux простыми словами?

Я 10 лет использую jQuery, и до меня сложно доходит архитектура React с которой я пытаюсь разобраться.
Вот к примеру у меня на странице много самостоятельных блоков, я их создаю как виджеты на yii, при этом один виджет может быть вложен в другой и так далее, можно их назвать компонентами. Бывает так что действие в одном компоненте влияет на другой компонент, к примеру в одном компоненте нажал кнопку "Сохранить", а другой компонент должен обновиться (перерисоваться). Я делаю так: нажали кнопку, я отправляю ajax, при успешном ответе я инициирую событие этого компонента $(document).trigger('widget_user#save'); А в других компонентах которые должны реагировать я слушаю это событие $(document).on('widget_user#save', function(){...}); Таким образом мои компоненты становяться независимыми, а всем кому интересно могут подписаться на его события.
Redux делает чтото похожее? Объясните пожалуйста простыми словами. И что называется состоянием?
  • Вопрос задан
  • 42490 просмотров
Пригласить эксперта
Ответы на вопрос 9
@KnightForce
Чтобы понять как работает Redux тебе нужно норм вкуривать React.
Хотя бы для того, чтобы не пугаться props.

Есть у тебя React. Это все просто JS объекты.
<Component /> - так позволяет писать движок jsx, который и React его использует.
Так как структура компонентная, ты должен думать как обновить компоненты в в другой части страницы.

Принцип такой: компонент обычно обновляется при получении новых свойств - props или когда меняется его объект состояния - state.

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

Что делает Redux:
Он не призывает отказываться от state.

Но есть общий контейнер данных. И когда данные меняются - меняются и компоненты, которые отображают именно эти данные.

Когда нужно что-то поменять - вызываешь dispatch - специальная функция reducer реагирует на это - и меняет данные как тебе нужно. Когда данные заменятся - компонент Propvider - вызывает рендер у своего дочернего компонента (тот что оборачивает Provider).
Например:
<Provider>
   <MyComponent />//Вот сюда Provider пробросит (запишет) новые props.
</Provider>


Записывает он это самое глобальное хранилище и все компоненты, для которых поменялись данные - перерисуются.

mapStateToProps - указывает какую часть этого глобального хранилища будет предоставлять provider.
Если у тебя оно такое:
{
   chunkStore: {},
   some: {}
}

То если mapStateToProps вернет{store: store.chunkStore}то Provider в props своего потомка пробросит такое: store: store.chunkStore. И ты будешь обращаться внутри к store, но там будет только часть chunkStore (не весь объект, а его поле).

mapDispatchToProps - т.к. subscribe нет, то это возвращает функции, которые могут внутри себя вызывать dispatch().

action - описывает то что и на что ты хочешь поменять. Какое поле и какие данные туда поместить.
Ответ написан
edtoken
@edtoken
Full-stack Javascript/Python Developer
В данном случае разное мышление (проектирование).

В вашем случае:
Логика идет от компонентов.
Допустим на странице пользователя есть label online/offline
Откуда брать значение, если нужно заблокировать окно чата в тот момент когда пользователь offline?
Что если таких действий не одно, а допустим штук 10?
Что если таких действий не одно, а допустим штук 10 и еще на разных страницах?
Куда вынести функцию, которая проверит статус пользователя?
Как её назвать чтобы не было конфликта имен?

Redux для меня в первую очередь подход.
1. Проектируется состояние (база данных фронта)
{user:{online:false}}
2. действие checkUserStatus (ajax/socket)

3. сколько угодно компонентов (которые не знают друг о друге ничего и имеют любое поведение, в зависимости от статуса пользователя)
компоненты могут ничего не уметь кроме как рендерить этот статус (label), или, могут быть более сложными и иметь логику + обработчики (кнопки, пр)
Ответ написан
jQuery "видит" весь DOM целиком. И манипулирует DOM-ом, доступ к которому предоставляет браузер. Но можно и по-другому.

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

Затем отделим состояние от поведения и представления. Состояние можно описать статической структурой данных, JSON-ом, например. А поведение - это чистая функция, из предыдущего состояния и некоего события (действия) делающая следующее состояние. Представление же "знает", как визуализировать состояние. Можно этот принцип воспроизвести от самых мелких компонент (не имеющих потомков) в нашем дереве и до корня. Тогда весь жизненный цикл приложения можно изобразить как цепочку состояний от некоего начального и до текущего, ведомую событиями (действиями).

Для того, чтобы это всё отобразить, не обязательно в ходе вычисления следующего состояния (или представления) сразу манипулировать DOM-ом. Можно построить из состояния и его представления фрагмент DOM-а, каким он должен получиться. А потом вычислить diff между этим построенным фрагментом (виртуальным DOM-ом) и реальным браузерным. И этот diff применить к реальному DOMу. Один раз. Получится быстро.

Насколько мне известно (поправьте, если это не так), Redux заимствован из Elm-а. Elm - это экосистема и функциональный язык, компилируемый в JS, сделанный для того, чтобы фронтэнд можно было разрабатывать удобно, быстро и без runtime-ошибок. По синтаксису - это адаптация Haskell-a. Ключевым элементом Elm-а является как раз вот эта самая архитектура. Советую подробнее почитать в первоисточнике. https://guide.elm-lang.org/architecture/

Кроме упомянутых особенностей эта архитектура также позволяет выполнять так называемую time-travelling отладку. Поскольку каждое состояние и каждое событие по пути от исходного до текущего можно залогировать и воспроизвести (ведь функция, вычисляющая следующее состояние у нас чистая).

С точки зрения функционального программирования, при таком подходе текущее состояние является результатом функции leftFold, применённой к исходному состоянию, последовательности событий (действий), приводящих к текущему и функции, умеющей вычислять следующее состояние.
Ответ написан
Redux — это конечный автомат. У него есть некоторое состояние (state), которое хранится в store. Состояние можно изменить, передав (dispatch) этому автомату некоторое сообщение (action). Изменением состояния занимается специальная функция — reducer. Она берёт начальное состояние и экшен и возвращает новое состояние.

Экшен выглядит примерно так:
{ type: 'MY_COOL_ACTION', payload: { a: 1, b: 2, c: 3 } }


Редьюсер — так:
function reducer(state, action) {
    switch (action.type) {
        case 'MY_COOL_ACTION':
            return Object.assign({}, state, {
                x: state.x + action.payload.a - action.payload.b,
                y: state.y + action.payload.c
            });

        default:
            // состояние по умолчанию
            return {
                x: 0,
                y: 0,
                z: 0
            };
    }
}
Ответ написан
copist
@copist
Мидл, хочешь стать синьором? http://copi.st/ExhE
jQuery - это принцип событий и модификации DOM, а сохранение состояний - дело второстепенное
Типичный механизм: что-то произошло (клик/скрол) -> что-то изменить в DOM, возможно что-то запомнить в JS

React - это принцип состояний, а изменение DOM или события - дело второстепенное
Возможно произошло событие -> обновить специальный объект (его называют модель)
Что-то изменилось в модели -> возможно обновить DOM, если модель как-то связана с HTML
Ответ написан
Voronar
@Voronar
Code typesetter
Редукс - это не самая лучшая реализация паттерна Наблюдатель.
Ответ написан
@DarkGenius
Full stack web developer
Redux предполагает, что все состояние вашего приложения хранится в одном месте (store), и единственный путь изменить это состояние - это отобразить старое состояние в новое с помощью специальной функции - редьюсера. Эта функция имеет сигнатуру (action, old_state) => new_state, где action можно понимать как "рецепт" вашего действия, например "добавить пользователя в базу".

Механизм рендеринга компонентов в react не знает явно о redux, для него лишь важно, что произошло изменение состояния тем или иным образом, на которое он должен отреагировать обновлением компонентов в соответствии с внутренней логикой.
Ответ написан
Redux - менеджер состояний, которые видят все компоненты. По сути можно наделать кучу изолированных состояний и соответственно к ним - по независимому типу изменений (мутаций). Далее к состояниям и мутациям реестрируем actions и в компонентах в зависимости от ивентов применяем эти actions.
Для меня это что-то типо mvc модель в фронтенде. Модель - состояние, контроллер - actions, а вьюхи - вызовы actions в шаблоне компонентов.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы