2016-03-29 7 views
1

私はReact/Reduxから始めて、子コンポーネントのラッパーのようなコンポーネントをFilterという名前で持っています。このフィルタコンポーネントには、それ自身の状態があり、子要素に渡す必要があります。子供のレスキューパスの状態を子に返す

export class Filter extends React.Component { 
    static propTypes = { 
     children: PropTypes.node 
    }; 

    render() { 
     return <div>{this.props.children}</div> 
    } 
} 


const mapStateToProps = function(state) { 
    return state.filter; 
}; 

export default connect((mapStateToProps), { 
    doFilter: (event) => { 
     return console.log(event.target.value); 
    } 
})(Filter) 

一つは、それが値を変更しますときdoFilterを呼び出すことになっている:

import Filter from 'components/filter'; 
.... 

export class CountryFilter extends React.Component { 
    render() { 
     return (
      <Filter> 
       <SelectField floatingLabelText="Country" value='all' fullWidth={true} onChange={this.props.doFilter}> 
        <MenuItem value='all' primaryText="All"/> 
        <MenuItem value='de' primaryText="Germany"/> 
        <MenuItem value='us' primaryText="United States"/> 
       </SelectField> 
      </Filter> 
     ); 
    } 
} 

問題がdoFilterが呼び出されないということです。 this.propsのログにCountryFilterコンポーネントがある場合は、空のオブジェクトを返します。

何か間違っていますか?

答えて

2

connect()の2番目の引数はオブジェクトであり、関数ではなく、dispatchを引数として受け取ります。 Here's the part of the docには、mapDispatchToPropsが記載されています。今mapDispatchToPropsは(と私は関数が、その中に真のReduxのアクションクリエイターでなければならないと信じて)オブジェクトを受け入れることができますが、私は一般的に、それは次のような構造で行わ見てきました:私たちはdispatchに結合していることから、また

const mapDispatchToProps = (dispatch) => { 
    return { 
     foo:() => dispatch(<action>) 
    } 
} 

propsの場合、コンソールへのロギングに反対するアクションをここで発したいと思うかもしれませんが、デバッグの目的でのみ行われたものと思われます。

const mapStateToProps = (state) => { 
    return { 
     filter: state.filter 
    } 
}; 

const mapDispatchToProps = (dispatch) => { 
    return { 
     doFilter: (event) => (
      dispatch({ 
       type: 'SET_FILTER_VALUE', 
       value: event.target.value 
      }) 
     ) 
    } 
}; 

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

また、代わりに単純なオブジェクトリテラル(すなわち{type: 'SET_FILTER_VALUE', value: event.target.value)を発するのは、我々は、おそらくのような、action creatorの形で他にこのアクションを定義したいと思います:

actions.js

const SET_FILTER_VALUE = 'SET_FILTER_VALUE'; 
const setFilterValue = (value) => { 
    return { 
     type: SET_FILTER_VALUE, 
     value 
    } 
} 

Filter.jsx

それは子供に至るまで、我々はまた、 doFilter/ setFilterValueが不定となります結果として、 Filterから小道具を渡していないかのように10
import { setFilterValue } from '../redux/actions'; 

...  

const mapDispatchToProps = (dispatch) => { 
    return { 
     doFilter: (event) => (
      dispatch(
       setFilterValue(event.target.value) 
      ) 
     ) 
    } 
}; 

... 

EDIT 1

ああ、見えます。 doFilterが確実に受け継がれるように、次のイディオムを使用します。そしてここから、我々はすべての子供に望むものを下に渡すことができます。

フィルター

render() { 
    const doFilter = this.props.doFilter; 
    return (
     <div> 
      { 
       React.Children.map(this.props.children, function(child) { 
        return React.cloneElement(
         child, 
         { doFilter: doFilter } 
        ); 
       }) 
      } 
     </div> 
    ) 
} 

EDIT 2

どの減速や店舗の創出かもしれないを表示するための要求がありましたこの例を探してください。そして、次のようになります。

ストアの作成を

import { createStore } from 'redux'; 
import reducer from './reducer'; 

const initialState = {}; 

const store = createStore(reducer, initialState); 
console.log(store.getState()); 
store.dispatch({type: 'SET_FILTER_VALUE', value: 2}; 
console.log(store.getState()); 

リデューサー

const Reducer = (state = {}, action) => { 
    switch(action.type) { 
     case 'SET_FILTER_VALUE': { 
      return { 
       ...state, 
       value: action.value 
      } 
     } 
     default: { 
      return state; 
     } 
    } 
} 

export default Reducer; 
+0

残念ながら動作しません。 'onChange'イベントは親コンポーネントまで伝搬しません:' Filter' –

+0

店舗を定義する場所と状態のフィルタ部分にレデューサーのコードを貼り付けることができますか? – marcacyr

+0

また、@lux、Reduxのそのビットのすばらしい故障とその動作方法。 – marcacyr

関連する問題