[英]Redux: Single container, multiple components
我對 React 和 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);
在這里,整個組件的所有狀態交互都集中在一個組件中。 此處的組件與第一種方法中的組件相同。 然而,這並沒有真正起作用:在 mapStateToProps 和 mapDispathToProps 中 ownProps 都是空的。 我可能誤解了 react-redux 連接的工作原理。
因此,鑒於這些事情,我有兩個問題:就容器和組件而言,構建此組件的最佳方法是什么? 其次,為什么 ownProps 在第二種方法中的工作方式與第一種方法不同?
感謝您的時間。
不確定我目前有關於結構的具體答案。 至於“ownProps”,它表示由其父組件專門傳遞給給定組件的道具。 由於您是connect()
-ing FilterController,這意味着“ownProps”將來自您渲染該組件的任何地方,例如: return <FilterController prop1="a" prop2={someVariable} />
。
根據您編寫這些映射函數的方式,看起來您確實想要連接 FilterInput 和 FilterButton 組件而不是 FilterController。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.