在我的Route组件中,我有一个Layout HOC,其中包含一些子组件。在此HOC中,我渲染了顶部和侧面栏,并且还将他连接到我的redux商店以获取当前用户并调度注销操作。问题是我定义了我的Hoc's Props,并将子代作为ReactNode,将用户作为UserType并将注销操作作为函数。但是在Route组件中,我收到一个错误,因为a没有将用户和操作作为道具传递。
我的HOC组件
interface Props extends RouteComponentProps {
children?: ReactNode
user?: UserType
logoutAction(): void
}
const AppLayout = (props: Props) => (
<Layout>
{/* <Sidebar {...props} /> */}
<Layout>
{/* <TopBar user={props.user} /> */}
<Content
style={{
margin: '24px 16px',
padding: 24,
background: '#fff',
minHeight: 280
}}
>
{props.children}
</Content>
</Layout>
</Layout>
)
const mapStateToProps = (state: AppStateType, ownProps: Props) => ({
...ownProps,
user: state.auth.currentUser
})
const mapDispatchToProps = (dispatch: Dispatch) => ({
logoutAction: () => dispatch(logoutUserSuccessAction())
})
export default withRouter(
connect(
mapStateToProps,
mapDispatchToProps
)(AppLayout)
)
我的路线组件
class Routes extends React.Component<Props> {
componentDidMount = () => {
this.props.fetchFields()
// this.props.fetchQuestions();
}
render() {
return (
<div
style={{
display: 'flex',
height: '100vh',
flexDirection: 'column',
width: '100vw'
}}
>
<AppLayoutContainer>
<React.Fragment>
<Switch>
<Route path="/" exact component={HomePageContainer} />
<Route path="/login" exact component={LoginPageContainer} />
{/* NEED AUTH HOC */}
<Route path="/gerencia" component={GerenciaPageContainer} />
<Route path="/relatorio" component={ReportPageContainer} />
<Route path="/exportar" component={ExportPageContainer} />
</Switch>
</React.Fragment>
</AppLayoutContainer>
</div>
)
}
}
我得到的错误:
Property 'logoutAction' is missing in type '{ children: Element; }' but required in type 'Readonly<Pick<Pick<Props, never> & Props, "user" | "children" | "logoutAction">>'.ts(2741)
AppLayoutContainer.tsx(20, 3): 'logoutAction' is declared here.
我正在尝试键入connect函数,但出现其他错误:
interface OwnProps extends RouteComponentProps {
children?: ReactNode
// user?: UserType
}
interface StateProps {
user?: UserType
}
interface DispatchProps {
logoutAction: () => void
}
type Props = StateProps & DispatchProps & OwnProps
const AppLayout = (props: Props) => (
<Layout>
{/* <Sidebar {...props} /> */}
<Layout>
{/* <TopBar {...props} /> */}
<Content
style={{
margin: '24px 16px',
padding: 24,
background: '#fff',
minHeight: 280
}}
>
<Button onClick={() => props.logoutAction()}>Fazer Logout</Button>
{props.children}
</Content>
</Layout>
</Layout>
)
function mapStateToProps(
state: AppStateType,
ownProps: OwnProps
): StateProps & OwnProps {
// ...ownProps,
return {
...ownProps,
user: state.auth.currentUser
}
}
const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
logoutAction: () => dispatch(logoutUserSuccessAction())
})
export default connect<StateProps, DispatchProps, void>(
mapStateToProps,
mapDispatchToProps
)(AppLayout)
我现在收到此错误:
Argument of type '(state: { auth: AuthReducerStateType; }, ownProps: OwnProps) => StateProps & OwnProps' is not assignable to parameter of type 'MapStateToPropsParam<StateProps, void, {}>'.
Type '(state: { auth: AuthReducerStateType; }, ownProps: OwnProps) => StateProps & OwnProps' is not assignable to type 'MapStateToPropsFactory<StateProps, void, {}>'.
Types of parameters 'state' and 'initialState' are incompatible.
Property 'auth' is missing in type '{}' but required in type '{ auth: AuthReducerStateType; }'.ts(2345)
getReducers.ts(41, 3): 'auth' is declared here.
答案 0 :(得分:1)
因此logoutAction
由redux提供,而不是由您手动提供。
您已根据需要将此道具标记为。 Typescript不知道它是redux组件,并且会基于mapDispatchToProps
传递此道具,因此它抱怨您没有提供它
在这种情况下,当外部lib(在您的情况下为redux)提供某些道具时,我通常将其标记为可选(这是有道理的,因为您实际上无法控制该道具的传递)
interface Props extends RouteComponentProps {
children?: ReactNode
user?: UserType
logoutAction()?: void // <<<--- ? added
}
应该解决问题