2015-10-16 36 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) => { ... }}