2

我正在使用 Redux(+React) 对分层结构进行操作,我有两个问题:

  1. 如何在 Redux 中实现多态?
  2. 如何让“动作冒泡”

我的问题表达得更准确:

  1. .

我正在使用 Redux 在 React 中制作结构代码编辑器。通过结构编辑器,我的意思是我有带有节点的树结构,我的应用程序应该在 AST 而不是纯文本上运行。

这些节点可以有各种类型(因为它是编辑 CSS 文件的编辑器,这些类型例如:“规则”、“声明”、“属性”、“值”,但更重要的是它们确实有一些类型) . 所以 JS 中有一些对象具有属性type,它type决定了它的...类型;)

所以假设我有这样的节点:

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

我希望能够写出这样的东西:

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

点击。但我希望点击 node of typerule会产生其他效果,而不是点击 node of type property。多态性(但我希望有一个反应组件<Node />来防止代码重复)。

我知道我可以通过 switch/case 或制作我自己的子功能来实现这一点(我的意思是将操作委托给功能),但我不想重新发明轮子。我认为对多态性的支持将对许多应用程序有用,而不仅仅是我的应用程序。

那么——如何在 Redux 中实现多态性?

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},
              ]
         } 
    ]
}

而且我有适当的 React 组件来呈现该结构(我有基于哑函数的无状态 React 0.14 组件,所以我不认为组件的代码现在非常重要)。无论如何,我得到<Node/>了代表单个 AST 节点的组件。

我希望该用户可以单击例如 id=3 ( {type: 'property', name: 'display', id: 3},) 处的节点,并且操作会自动“冒泡”到节点的父节点(在本例中为 id=2 的声明节点和 id=1 的规则节点)。

据我所知,Redux 中没有“动作冒泡”。也许应该是?或者也许我想实现的目标可以通过其他方式实现?(通过“动作冒泡”,我的意思是类似于浏览器中 JavaScript 事件中的“事件冒泡”,只是我想redux actions冒泡,我不希望 DOM 事件冒泡(这完全是另一回事)。我想减少动作冒泡。当我写“冒泡”时,我关注的是整体设计模式而不是实现。

这是我的两个问题:)

4

2 回答 2

3

我认为这是一个很好的问题,根据我对 redux 的理解,reducer 违反了 Open Closed 和 Single Responsibility 原则,因为它们在同一个 reducer 上您可以处理多个事件,如果您想添加其他处理程序,则需要更改减速机代码...

// 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) => { ... }}用它创建一次性的 a。

于 2016-03-02T16:54:28.190 回答
0
  1. 多态性

当您提到创建小型可重用函数时,我认为您已经找到了答案。我不同意多态性会是一个更好的选择。Redux 完全是关于函数式编程,而不是庞大的继承树。

  1. 动作冒泡。

请记住,在 Redux/Flux 中,您的商店是您唯一的事实来源。您的视图组件(即 React 元素)从存储中获取它们的数据。信息(即道具)从您的根元素自上而下地流向其子元素,然后流向其子元素,等等。

因此,您需要做的就是更新您的商店。其余的会自己处理。信息泡沫,但不是直接从孩子到父母。相反,它从孩子到商店(通过一个动作),然后才到父母。

于 2015-10-27T01:11:19.657 回答