1

私は React と Redux の両方にまったく慣れていないため、取り組んでいるケースのベスト プラクティスと技術的な解決策の両方について確信が持てません。ここでは、Dan Abramov によって定義されている「コンポーネント」と「コンテナー」を使用しています。

私が取り組んでいるコンポーネントは、フィルター コンポーネントの小さなコレクションです。1 つの入力テキスト フィールドと 2 つのボタンで、すべてエンティティのリストをフィルター処理します。私は2つのアプローチを試しました:

最初のアプローチ: 2 つのタイプのコンテナーの 3 つのインスタンスを含む単一のコンポーネント (対応するコンポーネントに接続されたコンテナー)。

最初に作ったのはこれでした。ここで、ルート コンポーネントは次のようになります。

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;

ここで参照されている 2 つのコンテナーは、接続されたコンポーネントと同様に、ほとんど予想どおりに見えます。例として 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;

このアプローチは機能しますが、2 つの異なるコンテナーを作成する必要はないと考えています。それが再び私を2回目の試みに導きました。

2 番目のアプローチ: 複数のコンポーネントを含む単一のコンテナー。

ここでは、より大きなコンテナを作成しました。

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);

ここでは、コンポーネント全体のすべての状態相互作用が 1 つのコンポーネントにまとめられています。ここでのコンポーネントは、最初のアプローチと同じです。ただし、これは実際には機能しません。ownProps は mapStateToProps と mapDispathToProps の両方で空です。react-redux 接続の仕組みを誤解している可能性があります。

これらのことを考えると、2 つの質問があります。コンテナーとコンポーネントの観点から、このコンポーネントを構造化する最良の方法は何ですか? 次に、2 番目のアプローチで ownProps が最初のアプローチと同様に機能しないのはなぜですか?

お時間をいただきありがとうございます。

4

1 に答える 1