我是新用户,正在努力解决以下问题。我有一个高阶组件(Hoc),可以将属性注入到包装的组件中。 HoC本身返回一个React.ComponentClass,它通过map和dispatch属性连接到redux存储。
我正在尝试将HoC与也连接到redux存储的组件一起使用。使用控制台日志输出语句,我可以看到包装组件中的所有属性除了未定义的调度属性外都已初始化。我不明白为什么在包装的组件中未定义调度属性???
我正在使用react-redux 7.1,并使用ConnectedProps
react-redux类型派生map和dispatch属性。
高阶组件
import cuid from 'cuid';
import React, { Component, ComponentType } from 'react';
import { ConnectedProps } from 'react-redux';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import { ApiErrorDialog } from './ApiErrorDialog';
import { ApiErrorListenerComponentProps } from './types';
import { connector } from './reduxConnect';
/**
* Type declarations
*/
type HocState = {
componentId: string;
};
type ReduxProps = ConnectedProps<typeof connector>;
export const withReduxErrorListener = <
BaseProps extends ApiErrorListenerComponentProps
>(
BaseComponent: ComponentType<BaseProps>,
) => {
/**
* Type declarations
*/
type HocProps = BaseProps & ReduxProps & RouteComponentProps;
type HocPropsExcludingBaseProps = Exclude<HocProps, BaseProps>;
console.log(
`withReduxErrorListener BaseProps => ${JSON.stringify(
BaseComponent.displayName,
)}`,
);
class ApiErrorListener extends Component<HocProps, HocState> {
static displayName = `withReduxErrorListener(${BaseComponent.name})`;
static readonly WrappedComponent = BaseComponent;
/**
* Some source code .....
*/
render(): JSX.Element {
const { ...restProps } = this.props;
console.log('hoc render()');
if (this.props.error.length > 0) {
return (
<React.Fragment>
/*{display custom error component here}*/
</React.Fragment>
);
} else {
// display base component
return (
<BaseComponent componentId={this.state.componentId} {...restProps} />
);
}
}
}
const ConnectedHoc = connector(ApiErrorListener as any);
const RoutedConnectedHoc = withRouter(ConnectedHoc as any);
return RoutedConnectedHoc;
};
包装的组件
type StateProps = {
isLoading: boolean;
courses: courseModels.Course[];
};
/**
* Redux dispatch and state mappings
*/
const dispatchProps = {
fetchCourses: apiCourseAction.request,
};
const mapStateToProps = (state: RootState): StateProps => ({
isLoading: state.courses.isLoadingCourses,
courses: courseSelectors.getReduxCourses(state.courses),
});
const connector = connect(
mapStateToProps,
dispatchProps,
);
type ReduxProps = ConnectedProps<typeof connector>;
/**
* Component property type definitions
*/
type Props = ReduxProps & ApiErrorListenerComponentProps; // &RouteComponentProps;
/**
* CourseList component
*/
const CourseListBase = ({
courses = [],
componentId,
fetchCourses,
isLoading,
}: Props): JSX.Element => {
// dispatch fetch course action on mount
useEffect(() => {
console.log('My properties are:=> ');
console.log(`courses :: ${JSON.stringify(courses)}`);
console.log(`componentId :: ${componentId}`);
console.log(`fetchCourses :: ${JSON.stringify(fetchCourses)}`);
console.log('COURSELIST FETCHING COURSES');
fetchCourses(requestFactories.getCourses(componentId));
}, [fetchCourses]);
if (isLoading) {
return <p>Loading...</p>;
}
return (
<div style={{ marginTop: 20, padding: 30 }}>
{
<Grid container spacing={2 as GridSpacing} justify="center">
{courses.map(element => (
<Grid item key={element.courseID}>
<Course course={element} />
</Grid>
))}
</Grid>
}
</div>
);
};
/**
* Exports
*/
const ConnectedCourseList = connector(withReduxErrorListener(CourseListBase));
export default ConnectedCourseList;
已更新26/11/2019 为了回应评论,我创建了一个codeandbox here。到目前为止,该问题尚未出现在codeandbox中,因此将在我的原始代码库中进行进一步调查。作为一名新的react-redux用户,对于我是否正确连接到codeandbox代码的高阶组件和基本组件中的redux存储的任何反馈,将不胜感激。
我还遇到了一个单独的问题,在代码沙箱的自述文件中对此进行了详细说明,为此我将提出一个单独的问题。
答案 0 :(得分:0)
设法使其起作用。该问题是由于不正确地将HoC连接到redux存储引起的,即组件已强制转换为任意存储。此问题在单独的question中得到了解决。
重构了HoC以遵循nested HOC pattern中的react-redux-typescript-guide
感谢该指南的作者在确定解决方案上的时间和耐心。感谢下降投票者提出了该问题的最小重现建议。
可以找到密码和盒子模型here