2015-10-16 14 views
1

我使用终极版(+反应)进行分层结构操作,我有两个问题:

  1. 如何实现终极版多态性?
  2. 如何使 “行动冒泡”

我的问题表达更准确:

我在使用Redux在React中进行结构代码编辑。通过结构编辑器,我的意思是我有树结构和节点,我的应用程序应该在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 />以防止代码重复)。

我知道我可以通过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}, 
       ] 
     } 
    ] 
} 

我有适当的做出反应的是渲染结构组件(我有哑功能为基础的无状态的阵营0.14组件,所以我不认为组件的代码现在非常重要)。无论如何,我得到代表单个AST节点的<Node/>组件。

我想用户可以点击例如节点上的id = 3({type: 'property', name: 'display', id: 3},),动作会自动“冒泡”到节点的父母(在这种情况下,声明节点在id = 2和规则节点在id = 1)。

据我所知,在Redux中没有“动作冒泡”。也许它应该是?或者,也许我想通过其他方式实现我想实现的目标? (通过“动作冒泡”我的意思是在浏览器中的JavaScript事件中类似于“事件冒泡”,只有我想redux actions冒泡,并且我不希望DOM事件冒泡(这完全是其他事情)。我想将行动减少到泡沫。当我写下“冒泡”时,我将整体设计模式而不是执行。

而这是我的两个问题:)

回答

0
  1. 多态性

我想你已经打了答案,当你提到的创建可重用的小功能。我不同意多态将是一个更好的选择。 Redux是关于函数式编程的,而不是庞大的继承树。

  1. 动作冒泡。

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

因此,你所需要做的就是更新你的商店。其余的照顾自己。信息气泡,但不是直接从孩子到父母。相反,它从孩子到商店(通过行动),然后才转到父母。

+0

1.多态性不是关于继承,而是“为不同类型的实体提供单一接口”。 (https://en.wikipedia.org/wiki/Polymorphism_(computer_science))。例如Redux reducer是多态的,因为根据动作类型,一个reducer函数应该有不同的反应:) – hex13

+0

2.我在“自上而下”的方法中遇到了问题,因为在每次操作之后,整个树被重新渲染并且应用程序非常慢。也许我做错了,但现在我自己将Redux连接到React(没有官方绑定),而不是“自上而下”,我将每个无状态元素放在智能有状态容器中,用于监听有趣状态片段的变化并重新渲染它的无声无子的孩子。 – hex13

1

我认为这是一个很好的问题,基于我对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) => { ... }}