簡體   English   中英

Redux:單個容器,多個組件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM