2016-04-06 58 views
1

我對React和Redux都很陌生,對於正在處理的案例,我不確定最佳實踐和技術解決方案。我使用Dan Abramov here定義的「組件」和「容器」。Redux:單容器,多組件

我正在處理的組件是過濾組件的一個小集合:一個輸入文本字段和兩個按鈕,全部過濾實體列表。我試過兩種方法:

第一種方法:單個組件包含兩種類型的容器的三個實例,連接到相應組件的容器。

這是我第一次做的。在這裏,根組件如下所示:

import React, { PropTypes, Component } from 'react'; 
import Config from '../../config'; 
import FilterInput from '../containers/FilterInput'; 
import FilterLink from '../containers/FilterLink' 

class FilterController extends Component { 
    render() { 
     return (
      <div className='filterController'> 
       <FilterInput displayName="Search" filterName={Config.filters.WITH_TEXT} /> 
       <FilterLink displayName="Today" filterName={Config.filters.IS_TODAY} /> 
       <FilterLink displayName="On TV" filterName={Config.filters.ON_TV} /> 
      </div> 
     ) 
    } 
} 
export default FilterController; 

此處引用的兩個容器看起來非常象預期的那樣做連接的組件。我將顯示FilterLink爲例:

import React, { PropTypes, Component } from 'react'; 
import {connect} from 'react-redux'; 
import {toggleFilter} from '../actions'; 
import FilterButton from '../components/filterbutton' 

const mapStateToProps = (state, ownProps) => { 
    return { 
     active: !!state.program.filters[ownProps.filterName] 
    } 
} 

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
     onClick:() => { 
      dispatch(toggleFilter(ownProps.filterName, ownProps.input)) 
     } 
    } 
} 

const FilterLink = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(FilterButton) 

export default FilterLink 

以及相應的FilterButton組件:

import React, { PropTypes, Component } from 'react'; 

class FilterButton extends Component { 

    render() { 
     return (
      <button className={this.props.active ? 'active' : ''} 
        onClick={this.props.onClick}> 
       {this.props.displayName} 
      </button> 
     ) 
    } 
} 

FilterButton.propTypes = { 
    active: PropTypes.bool.isRequired, 
    displayName: PropTypes.string.isRequired, 
    onClick: PropTypes.func.isRequired, 
    filterName: PropTypes.string.isRequired 
}; 

export default FilterButton; 

這種方法的工作原理,但我認爲它不應該是必要建立兩個不同的容器。這再次引導我進行第二次嘗試。

第二種方法:單個容器包含多個組件。

在這裏,我提出了更大的容器:

import React, { PropTypes, Component } from 'react'; 
import Config from '../../config'; 
import {connect} from 'react-redux'; 
import {toggleFilter} from '../actions'; 
import FilterButton from '../components/filterbutton' 
import FilterInput from '../components/filterinput' 

class FilterContainer extends Component { 
    render() { 
     const { active, currentInput, onChange, onClick } = this.props; 
     return (
      <div className='filterController'> 
       <FilterInput displayName="Search" filterName={Config.filters.WITH_TEXT} currentInput={currentInput} onChange={onChange} /> 
       <FilterButton displayName="Today" filterName={Config.filters.IS_TODAY} active={active} onClick={onClick}/> 
       <FilterButton displayName="On TV" filterName={Config.filters.ON_TV} active={active} onClick={onClick}/> 
      </div> 
     ) 
    } 
} 

const mapStateToProps = (state, ownProps) => { 
    return { 
     active: !!state.program.filters[ownProps.filterName], 
     currentInput: state.program.filters[ownProps.filterName] ? state.program.filters[ownProps.filterName].input : '' 
    } 
} 

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
     onClick:() => { 
      dispatch(toggleFilter(ownProps.filterName, ownProps.input)) 
     }, 
     onChange: newValue => { 
      dispatch(toggleFilter(ownProps.filterName, newValue.target.value)) 
     } 
    } 
} 

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

在此,對整個組件的所有狀態的交互被收集在一個單一的成分,它。這裏的組件與第一種方法相同。但是,這並不是真的有效:ownProps在mapStateToProps和mapDispathToProps中都是空的。我可能誤解了react-redux連接的工作原理。

因此,考慮到這些事情,我有兩個問題:根據容器和組件,構建此組件的最佳方法是什麼?其次,爲什麼在第二種方法中沒有像第一種方法那樣擁有類似的工作?

謝謝你的時間。

回答

1

不確定我現在有關於結構的具體答案。至於「ownProps」,則表示專門由其父代傳遞給定組件的道具。由於您是connect() -ing FilterController,這意味着「ownProps」將來自您呈現該組件的任何位置,例如:return <FilterController prop1="a" prop2={someVariable} />

根據你如何編寫這些映射函數,看起來你確實想連接FilterInput和FilterButton組件,而不是FilterController。

相關問題