调用getProjects时报错:getProjects is not a function
解决React-Boilerplate中useEffect调用getProjects提示“不是函数”的问题
问题根源
- 未导入action中的getProjects函数:你的
mapDispatchToProps里调用的getProjects(),根本不是action文件里定义的那个函数,而是你在返回对象里刚声明的同名函数,导致引用混乱。 - propTypes缺失声明:组件用到了
getProjects作为props,但propTypes里只声明了dispatch,不符合规范也可能引发校验警告。
修复步骤
1. 导入action中的getProjects
在组件文件顶部,引入action里的getProjects函数(注意路径要和你的实际文件结构匹配):
import { getProjects } from './action';
2. 修正mapDispatchToProps的引用冲突
现在mapDispatchToProps里的dispatch(getProjects())就能正确指向action里的函数了:
function mapDispatchToProps(dispatch) { return { dispatch, getProjects: () => dispatch(getProjects()), }; } // 嫌麻烦的话也可以用redux的bindActionCreators简化: // import { bindActionCreators } from 'redux'; // function mapDispatchToProps(dispatch) { // return bindActionCreators({ getProjects }, dispatch); // }
3. 补上propTypes的声明
给getProjects添加必填的函数类型声明:
Projects.propTypes = { dispatch: PropTypes.func.isRequired, getProjects: PropTypes.func.isRequired, };
4. 完善useEffect的依赖数组
把getProjects加入useEffect的依赖列表,避免闭包导致的潜在问题:
useEffect(() => { getProjects(); }, [getProjects]);
修复后的完整组件代码
import React, { useEffect } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { createStructuredSelector } from 'reselect'; import { compose } from 'redux'; import injectReducer from 'utils/injectReducer'; import injectSaga from 'utils/injectSaga'; import { makeSelectProjects } from './selectors'; import reducer from './reducer'; import saga from './saga'; import { getProjects } from './action'; export function Projects({ getProjects }) { useEffect(() => { getProjects(); }, [getProjects]); return ( <div> <p>Testing Projects</p> </div> ); } Projects.propTypes = { dispatch: PropTypes.func.isRequired, getProjects: PropTypes.func.isRequired, }; const mapStateToProps = createStructuredSelector({ projects: makeSelectProjects(), }); function mapDispatchToProps(dispatch) { return { dispatch, getProjects: () => dispatch(getProjects()), }; } const withConnect = connect(mapStateToProps, mapDispatchToProps); const withReducer = injectReducer({ key: 'projects', reducer }); const withSaga = injectSaga({ key: 'projects', saga }); export default compose( withReducer, withSaga, withConnect )(Projects);
内容的提问来源于stack exchange,提问作者user15003460
相关产品推荐
相关产品推荐

