1

Я использую Redux (+ React), чтобы работать на иерархических структурах и у меня есть два вопроса:Полиморфизм и действие, пузырящиеся в Редуксе?

  1. как реализовать полиморфизм в Redux?
  2. как сделать "действия бульканье"

Мои вопросы высказанное более точно:

  1. .

Я делаю редактор структурного кода в React, используя Redux. Структурным редактором я имею в виду, что у меня есть древовидная структура с узлами в нем, и мое приложение должно работать с AST, а не с обычным текстом.

Эти узлы могут иметь различные типы (потому что это редактор для редактирования файлов CSS, такими типами являются: «правило», «объявление», «свойство», «значение», но более важно, чтобы у них были некоторые типа вообще). Таким образом, есть объекты в JS, которые имеют свойство type и его type определяет его ... тип;)

Так предположим, что у меня есть узел, как это:

{ 
    type: 'property', 
    id: 4, 
    rule: '.content > ul > li', 
    children: [...blah blah......] 
} 

И я хотел бы быть в состоянии написать что-то как то:

store.dispatch({type: 'click', nodeId: 4})

для мыши. Но я ожидал бы, что щелчок по узлу типа rule будет иметь другой эффект, чем щелчок по узлу типа property. Полиморфизм (но я бы хотел, чтобы один ОДИН реагировал на компонент <Node />, чтобы предотвратить дублирование кода).

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

Итак - как добиться полиморфизма в Редуксе?

2.,
Второй вопрос о действии пузыри. Потому что я получил древовидную структуру, например, такие как этот:

{ 
    type: 'rule', 
    rule: 'body div', 
    id: 1, 
    children: [ 
     { 
       type: 'declaration', 
       id: 2, 
       children: [ 
        {type: 'property', name: 'display', id: 3}, 
        {type: 'value', value: 'block', id: 4}, 
       ] 
     } 
    ] 
} 

И у меня есть соответствующие Реагировать компоненты, которые делают эту структуру (я имею немую функцию на основе без гражданства Реагировать 0.14 компонентов, так что я не думаю, что код компоненты очень важно сейчас). Во всяком случае, я получил компонент <Node/>, который представляет собой единый узел АСТ.

Я бы хотел, чтобы этот пользователь мог щелкнуть, например, на узле с id = 3 ({type: 'property', name: 'display', id: 3},), и действие автоматически «пузырилось» с родителями узла (в этом случае к узлу объявления при id = 2 и к узлу правила с идентификатором = 1).

Насколько я знаю, в Redux нет «пузыряния действий». Может быть, так и должно быть? Или, может быть, то, что я хотел бы достичь, можно было сделать другими способами? («bubbling action» я имею в виду что-то похожее на «пузырь событий» в событиях JavaScript в браузере, только я хотел бы redux actions пузырить, и я НЕ хочу, чтобы события DOM пузырились (это совсем другое дело).Я хотел бы уменьшить действие на пузырь. Когда я писал «пузырящийся», я рассматривал общую схему проектирования, а не реализацию.

И это были мои два вопроса :)

ответ

0
  1. полиморфизм

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

  1. Действие пузыри.

Помните, что в Redux/Flux ваш магазин является вашим единственным источником правды. Компоненты вашего представления (т. Е. Элементы React) получают свои данные из хранилища. Информация (т. Е. Реквизит) течет сверху вниз от вашего корневого элемента к его дочерним элементам, а затем к его дочерним элементам и т. Д.

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

+0

1. Полиморфизм не касается наследования, а «представляет собой единый интерфейс для объектов разных типов». (https://en.wikipedia.org/wiki/Polymorphism_(computer_science)). Например, редукторы Redux являются полиморфными, потому что одна функция редуктора должна реагировать по-разному в зависимости от типа действия :) – hex13

+0

2. У меня были проблемы с «потоком сверху вниз», потому что после того, как каждое действие целого дерева было отменено, а приложение было ужасно медленным. Возможно, я делал это неправильно, но теперь я подключаю Redux к React самостоятельно (без официальных привязок), а вместо «flow down-down» я помещаю каждый элемент без состояния в интеллектуальный контейнер со статусом, который слушает изменения интересного фрагмента состояния и rerender его немого ребенка без гражданства. – hex13

1

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

// This is kind of the standard approach 
// It has a big switch case that knows how to handle many actions (single responsibility violation). 
// The more actions you have the bigger this function becomes, to handle an other even you need to change the reducer (open closed violation). 
export default function reducer(state = INITIAL_STATE, action) { 
    switch (action.type) { 
    case 'SET_ENTRIES': 
    return setEntries(state, action.payload); 
    case 'NEXT': 
    return next(state); 
    case 'VOTE': 
    return vote(state, action.payload) 
    } 

    // return the current state if the action you try to use dont exist 
    return state; 
} 

в случае выше действий будет как {type: 'VOTE', payload: {...}} ... Я лично не нравится этот подход, поскольку он не является гибким, и я думаю, что мы можем сделать многое лучше с использованием полиморфизма ниже приведен пример более гибкого полиморфного редуктора:

// This is a polymorphic aprorach that conforms to all SOLID principles 
// This is much simpler and will raise an error if the action does not exist 
export default function reducer(state = INITIAL_STATE, action) { 
    return action.handler(state, action.payload); 
} 

В случае выше действия будут выглядеть {handler: vote, payload: {...}} этот подход является гораздо более гибким, вы можете даже создавать одноразовые в {handler: (state) => { ... }} с этим.