我对React和Redux都很陌生,而且我不确定我正在研究的案例的最佳实践和技术解决方案。我正在使用Dan Abramov here定义的“组件”和“容器”。
我正在处理的组件是一小组过滤器组件:一个输入文本字段和两个按钮,全部过滤实体列表。我尝试了两种方法:
第一种方法:单个组件包含两种类型容器的三个实例,容器连接到相应的组件。
这是我第一次做的。这里,根组件如下所示:
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连接是如何工作的。
所以,鉴于这些事情,我有两个问题:在容器和组件方面,构建这个组件的最佳方法是什么?其次,为什么不会像第一种那样在第二种方法中使用自己的作品?
感谢您的时间。
答案 0 :(得分:1)
目前还不确定我有关于结构的具体答案。对于&#34; ownProps&#34;,它表示由其父级专门传递给给定组件的道具。因为你是connect()
- 过滤器控制器,这意味着&#34; ownProps&#34;将来自您呈现该组件的任何位置,例如:return <FilterController prop1="a" prop2={someVariable} />
。
根据您编写这些地图函数的方式,看起来您真的想要连接FilterInput和FilterButton组件而不是FilterController。