[英]React Redux - cannot use a pass down a component's method to the children - undefined error
[英]React redux pass state down to children
我从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
。 如果我在CountryFilter
组件中对此this.props
进行日志记录,它将返回一个空对象。
难道我做错了什么?
似乎connect()
的第二个参数是一个对象,而不是一个函数,该函数又接受dispatch
作为参数。 这是文档中提到mapDispatchToProps
。 现在mapDispatchToProps
可以接受一个对象(我相信其中的功能必须是名副其实的Redux动作创建者),但是我通常看到它是通过以下结构完成的:
const mapDispatchToProps = (dispatch) => {
return {
foo: () => dispatch(<action>)
}
}
另外,由于我们将dispatch
绑定到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
),我们可能还想以动作创建者的形式定义该动作,例如:
actions.js
const SET_FILTER_VALUE = 'SET_FILTER_VALUE';
const setFilterValue = (value) => {
return {
type: SET_FILTER_VALUE,
value
}
}
Filter.jsx
import { setFilterValue } from '../redux/actions';
...
const mapDispatchToProps = (dispatch) => {
return {
doFilter: (event) => (
dispatch(
setFilterValue(event.target.value)
)
)
}
};
...
编辑1
嗯,似乎我们也没有将道具从Filter
传递给它的孩子,因此doFilter
/ setFilterValue
将是未定义的。 我们将使用以下惯用语来确保doFilter
被传递。 从这里,我们可以将任何希望的东西传递给任何孩子:
过滤
render() {
const doFilter = this.props.doFilter;
return (
<div>
{
React.Children.map(this.props.children, function(child) {
return React.cloneElement(
child,
{ doFilter: doFilter }
);
})
}
</div>
)
}
编辑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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.