为什么在将 react-redux 与打字稿一起使用时,未为连接的高阶组件中的已连接包装组件定义调度属性?



我是新用户,正在努力解决以下问题。我有一个高阶组件 (Hoc(,它将属性注入到包装的组件。HoC 本身返回一个 React.ComponentClass,该 React.ComponentClass 使用映射和调度属性连接到 redux 存储。

我正在尝试将 HoC 与也连接到 redux 存储的组件一起使用。使用控制台日志输出语句,我可以看到包装组件中的所有属性都已初始化,除了未定义的调度属性。我不明白为什么包装的组件中未定义调度属性????

我正在使用 react-redux 7.1 并使用ConnectedPropsreact-redux 类型派生映射和调度属性。

高阶组件

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为了回应评论,我在这里创建了一个代码沙箱。到目前为止,该问题尚未在代码沙箱中表现出来,因此将在我的原始代码库中进一步调查。作为一个新的 react-redux 用户,任何关于我是否正确连接到代码沙箱代码的高阶组件和基本组件中的 redux 存储的反馈,将不胜感激。

我还遇到了一个单独的问题,在代码沙箱的自述文件中详细说明,我将为此提出一个单独的问题。

设法让它工作。该问题是由于错误地将 HoC 连接到 redux 存储引起的,即组件被强制转换为任何组件。这个问题在一个单独的问题中得到了解决。

重构了 HoC 以遵循 react-redux-typescript-guide 中的嵌套 HOC 模式

感谢指南作者在确定解决方案方面的时间和耐心。感谢反对者建议对问题的最小再现。

代码沙盒模型可以在这里找到

最新更新