2015-10-24 19 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