我是新的react-redux用户,试图将更高阶的组件连接到react-redux存储。在将状态映射到props函数中,我正在使用ownProps参数来过滤状态。但是,我尝试在OwnProps中使用的属性始终未定义。有没有人经历过类似的事情?
Redux属性
import { connect } from "react-redux";
import { clearErrorAction } from "../features/errors/actions";
import { filterErrors } from "../features/errors/selectors";
import { FailureNotify } from "../features/errors/types";
import { HocComponentProps } from "./types";
import { RootState } from "typesafe-actions";
type StateProps = {
error: FailureNotify[];
};
export const mapStateToProps = (
state: RootState,
ownProps: HocComponentProps
): StateProps => {
// uniqueId property is always undefined here???
console.log(`withErrorListener mapStateToProps => ${ownProps.uniqueId}`);
return {
error: filterErrors(state.errors as StateProps, ownProps)
};
};
export const dispatchProps = {
clearError: clearErrorAction
};
export const connector = connect(
mapStateToProps,
dispatchProps
);
高阶组件
import * as React from "react";
import { ConnectedProps } from "react-redux";
import { RouteComponentProps, withRouter } from "react-router-dom";
import { connector } from "./redux";
import { FailureNotify } from "../features/errors/types";
/**
* Type declarations
*/
type ReduxProps = ConnectedProps<typeof connector>;
type ExpectedProps = { uniqueId: string };
/**
* Internal components
*/
type ErrorInfoProps = { info: FailureNotify } & ReduxProps &
RouteComponentProps;
const ErrorInfo = ({
info,
clearError,
history
}: ErrorInfoProps): JSX.Element => {
function goHome(): void {
console.log("Go home button has been clicked");
clearError(info.fromAction, info.fromComponent, history, "/");
}
return (
<React.Fragment>
<p>Error {info.message}</p>
<p>Received from action {info.fromAction}</p>
<p>Received for component id {info.fromComponent}</p>
<button onClick={goHome}>Home</button>
</React.Fragment>
);
};
/**
* HoC that renders errors on the redux store rasied for a component.
* @param BaseComponent The component to wrap should have uniqueId property
*/
export const withErrorListener = <BaseProps extends ExpectedProps>(
BaseComponent: React.ComponentType<BaseProps>
) => {
/**
* Type declarations
*/
type HocProps = BaseProps & ReduxProps & RouteComponentProps;
class ErrorListener extends React.Component<HocProps, {}> {
static displayName = `withErrorListener(${BaseComponent.name})`;
static readonly WrappedComponent = BaseComponent;
/**
* Render error if there is one to display, otherwise render the base component
* @returns Rendered error if error occurred. Rendered base component if no error occurred.
*/
render() {
const { ...restProps } = this.props;
console.log(`withErrorListener [error_count=${this.props.error.length}]`);
if (this.props.error.length > 0) {
return <ErrorInfo info={this.props.error[0]} {...restProps} />;
} else {
return <BaseComponent {...restProps as BaseProps} />;
}
}
}
const ConnectedHoc = connector(ErrorListener as any);
const RoutedHoc = withRouter(ConnectedHoc as any);
return RoutedHoc;
};
我正在此source file
的末尾创建 withErrorListener 高阶组件的实例const PostsListConnectedWithId = connector(withId(PostsListBase));
export const PostsListWithErrorListener = withErrorListener(
PostsListConnectedWithId
);
PostsListBase 的源代码在同一source file
中可用PostsListsWithErrorListener 在App组件中呈现。
始终未定义的属性是 uniqueId ,并由 withId 高阶组件here注入到基础组件中。 codeandbox内的控制台日志输出显示 uniqueId 属性值。