这是我的组件UserHandler
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import * as actionCreators from '../../store/actions/actions';
class UserHandler extends Component {
componentDidMount() {
const { onInitUsers } = this.props;
onInitUsers();
}
render() {
// some code
return (
{/* SOME JSX */}
);
}
}
const mapStateToProps = state => ({
// state to props mapping
});
const mapDispatchToProps = dispatch => ({
onUserEdition: username => dispatch(actionCreators.editUser(username)),
onUserSelection: username => dispatch(actionCreators.fetchSelectedUser(username)),
onInitUsers: () => dispatch(actionCreators.initUsers()),
});
// PropTypes definition and defaultProps
export default connect(mapStateToProps, mapDispatchToProps)(UserHandler);
在我的actionCreators
文件中,这是我定义的内容:
const initUsersStart = createAction(INIT_USERS_START);
const setUsers = createAction(SET_USERS, users => ({ users }));
const initUsersError = createAction(INIT_USERS_ERROR, error => ({ error }));
const initUsers = () => (dispatch) => {
dispatch(initUsersStart());
return axios.get('/users')
.then(
response => dispatch(setUsers(response.data)),
)
.catch(
error => dispatch(initUsersError(error)),
);
};
当我在onInitUsers();
函数中评论componentDidMount()
调用时,我不再遇到错误。我想了解为什么这会引发此错误。
最后,这是我创建store
的方法:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import reducer from './store/reducers/reducers';
const store = createStore(
reducer, /* preloadedState, */
applyMiddleware(thunk),
/* eslint-disable no-undef */ /* eslint-disable no-underscore-dangle */
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
/* eslint-enable */
);
// const store = createStore(reducer);
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
/* eslint-disable no-undef */
document.getElementById('root'),
/* eslint-enable */
);
registerServiceWorker();
请注意,我之前已经做过一些研究,以找出可能导致这种错误的根本原因,并且看来它可能源于多种原因。我检查了发现的内容,但没有帮助。
答案 0 :(得分:2)
返回axios调用,因此无论逻辑遵循哪种路径,Redux都会根据需要返回对象。
const initUsers = () => (dispatch) => {
dispatch(initUsersStart());
return axios.get('/users')
.then(
response => dispatch(setUsers(response.data)),
)
.catch(
error => dispatch(initUsersError(error)),
);
};
测试完代码后,我认为问题还在于商店配置。中间件应作为createStore
函数的最后一个参数应用:
const store = createStore(
reducer, /* preloadedState, */
/* eslint-disable no-undef */ /* eslint-disable no-underscore-dangle */
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
/* eslint-enable */
applyMiddleware(thunk),
);
我用redux v.4.0.0和react-redux v.5.0.7进行了测试。
答案 1 :(得分:1)
这是在the React-Redux issues list上发布的,我在那里回答了。为了完整起见,我将粘贴我的解决方案。
首先,根本问题是,不是普通动作对象的东西正在到达实际的商店。您可以在Redux源代码的dispatch
函数中放置一个断点,以查看实际值(或在项目的node_modules
文件夹中编辑Redux的副本以添加一些日志记录)。
实际上,我认为我看到了问题。真正的问题是,您要将两个单独的商店增强器传递给createStore
。一个是applyMiddleware
的中间件增强器,另一个是Redux DevTools扩展。您需要将它们“一起”组合成一个组合的增强器。有关如何正确执行此操作的可复制粘贴示例,请参见Redux文档中的Configuring Your Store页。
另外两个建议:
您可以使用“对象简写”来代替手动编写mapDispatch
函数,而只需将充满动作创建者的对象直接传递给connect
。您已经有了import * as actionCreators
语句中充满动作创建者的对象,因此您可以这样做:export default connect(mapState, actionCreators)(UserHandler)
。 (也就是说,函数名称与所需的prop名称不同,因此您可能需要创建一个新对象,例如{onUserSelection : actionCreators.fetchSelectedUser}
并传递该对象。)
此外,我们正在使用的redux-starter-kit
package具有一个为您设置商店的功能,并自动添加redux-thunk
和DevTools扩展。您可能要尝试使用它而不是自己设置商店。
答案 2 :(得分:0)
问题是,您正在调用onInitUsers()
来调度动作,因为它位于dispatch()
函数内部。如果分派操作,则需要返回键为type
和可选负载的对象。
您需要的是bindActionCreators
中的mapDispatchToProps
函数,如下所示:
import { bindActionCreators } from "redux";
const mapDispatchToProps = dispatch => ({
onUserEdition: username => dispatch(actionCreators.editUser(username)),
onUserSelection: username => dispatch(actionCreators.fetchSelectedUser(username)),
onInitUsers: bindActionCreators(actionCreators.initUsers, dispatch),
});
现在您已经将调度功能绑定到了initUsers函数,可以像我们想要的那样使用它了。
编辑:尝试将您的onInitUser
函数更改为以下内容:
const initUsers = () => (dispatch) => {
dispatch(initUsersStart());
return dispatch({
type: 'GET_USER',
payload: axios.get('/users')
.then(
response => dispatch(setUsers(response.data)),
)
.catch(
error => dispatch(initUsersError(error)),
);
});
};