2015-10-24 41 views
1

我嘗試在redux中創建可重用組件。
背後的想法是,我創建了一個智能組合框,並將其放置在其他組件或智能組件內數次。使用redux嵌套的智能組件

讓我們假設從這個組合框中唯一的工作是顯示國家,允許添加新的國家並告訴父母選擇哪個國家。

父母不必將可用的國家傳遞給組合框只有onValueChanged事件,因此父母知道選擇哪個國家。

這導致以下結構(該項目不是真正的國家保持它的簡單,但你應該得到它背後的想法):

//Constants (appConstants.ts) 
export const SmartCombobox = { 
    ADD_ITEM: 'SMART_COMBOBOX/ADD_ITEM' 
} 

//Action creator (smartComboboxAction.ts) 
import { SmartCombobox } from '../constants/appConstants'; 

export function AddItem() { 
    return { 
     type: SmartCombobox.ADD_ITEM 
    }; 
} 

//Reducer (smartCombobox.ts) 
import { SmartCombobox } from '../constants/appConstants'; 

const initialState = ['Item 1'] 

export default function items(state = initialState, action) { 
    switch (action.type) { 
     case SmartCombobox.ADD_ITEM: 
      let items = ['Item' + Math.random().toString()] 
      return state.concat(items); 
     default: 
      return state; 
    } 
} 

//Container (smartCombobox.ts) 
import { bindActionCreators } from 'redux'; 
import { connect } from 'react-redux'; 
import { default as SmartCombobox } from '../components/combobox'; 
import * as ComboboxActions from '../actions/smartComboboxAction'; 

function mapStateToProps(state) { 
    return { 
     items: state.items   
    }; 
} 

function mapDispatchToProps(dispatch) { 
    return { 
     comboboxActions: bindActionCreators(<any>ComboboxActions, dispatch) 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(SmartCombobox); 

然後我可以像這樣使用我的組件裏面或智能組件。 當我添加一個新項目時,包含我的smartCombobox的每個組件都將被同步並具有確切的項目數量。

//Component (combobox.tsx) 
import * as React from 'react'; 

interface SmartComboboxProps { 
    items?: Array<any>, 
    comboboxActions?: any, 
    onValueChanged: Function 
} 

export default class SmartCombobox extends React.Component<SmartComboboxProps, any> { 
    onValueChanged(event:any) { 
     let selectedValue = event.target.value; 
     const { onValueChanged } = this.props; 

     onValueChanged(selectedValue); 
    } 

    componentDidMount() { 
     // Call value changed for first selected item   
     this.props.onValueChanged(this.props.items[0]); 
    } 

    render() { 
     const { comboboxActions } = this.props; 

     let options = this.props.items.map(function (o) { 
      return <option key={o} value={o}>{o}</option> 
     }); 

     return (
      <div> 
       <select style={{ width: "200px" }} name="SmartCombobox" onChange={ this.onValueChanged.bind(this) } > 
        { options } 
       </select> 
       <button onClick={ comboboxActions.AddItem }>Add item</button> 
      </div> 
     ); 
    } 
} 

Final result (Image)

這是爲可重用的組件正確的做法?
或者我可能會忘記任何陷阱?

也有人認爲組合框應該直接連接到API,因爲應用程序不應該知道這裏發生了什麼。
但是這樣會破壞通量的想法,因爲我需要這個組件等
我是反對這種想法內的狀態...

+0

我不認爲這種方法是錯誤的,如果它的工作。我不認爲將組件連接到API比保留它更好,因爲當它加載數據時(例如,如果您有全局加載gif),您可能想知道應用程序中的其他位置。另一方面,您可以使用Web組件進行反應,並且該模式不是反模式。您可以使用聚合物組件,將其掛鉤到API中,這不會是世界上最糟糕的事情。 –

回答

0

這是爲可重用的組件正確的做法? 或者有可能是我可能會忘記的任何陷阱

這種方法很好。

也有人認爲組合框應該直接連接到api,因爲應用程序不應該知道這裏發生了什麼。

你就在這裏。真理的源頭(或者說真相設定者)只需要是真實的源頭,因此不能是組件。

+0

謝謝。也這麼覺得 :)。我現在必須考慮的一件事是,如果我應該觸發在父組件或智能組合框內填充組合框的操作。好處是,只有當我在componentDidMount之後的父級中調用該動作時,該動作纔會被髮送一次。 – datoml

+0

'我現在必須考慮的一件事是,如果我應該觸發在父組件或智能組合框內填充組合框的操作'智能組合框應該從REDEX存儲庫填充。不*只是'redux-react'' @ connect' – basarat

+0

對不起,我的意思是我應該在哪裏調用填充動作。我的智能組合框已連接到商店。但是當我在componentDidMount之後的組合框內調用這個動作時,它會被調用3次。但是當我在componentDidMount方法中的父級以外調用該操作時,它只會被調用一次。但是當我把它嵌入父代之後,也許有機會忘記它。我個人比較喜歡這種叫法。 – datoml