类型“{}”缺少类型中的以下属性

时间:2021-01-15 18:52:49

标签: reactjs typescript react-router

在我的 React 项目中,我的 App 组件出现以下错误。

Type '{}' is missing the following properties from type 'Pick<ClassAttributes<App> & RouteChildrenProps<{}, unknown> & { userData: UserDataType | undefined; userRightList: UserRightListType[] | undefined; userPermissionList: string[] | undefined; } & { ...; }, "ref" | ... 3 more ... | "key">': history, location, matchts(2739)

以下是我的 index.tsx 文件代码:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import App from './App';
import reportWebVitals from './reportWebVitals';
import reduxStore from './redux/store';

ReactDOM.render(
  <Provider store={reduxStore.store}>
    <BrowserRouter>
      <App /> // getting the error here
    </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

reportWebVitals();

以下是我的 App.tsx 文件代码:

import { Component, Fragment } from 'react';
import { connect } from 'react-redux';
import { RouteComponentProps } from 'react-router-dom';
import ErrorBoundary from './components/ErrorBoundary';
import { getUserByToken, getUserRights, setUserRights } from './redux/actions';
import { ReduxStateType } from './type-definitions';
import { isAuthenticated } from './utils/is-authenticated';

type StoreProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = typeof mapDispatch;

type PropsType = RouteComponentProps & StoreProps & DispatchProps;

class App extends Component<PropsType, any> {
  componentDidMount() {
    const {
      userData,
      getUserByToken,
      getUserRights,
      userRightList,
    } = this.props;
    const isAuth = isAuthenticated(userData);
    if (!userData?.username && isAuth) {
      getUserByToken();
    }
    if (userRightList?.length === 0 && isAuth) {
      getUserRights();
    }
  }

  componentDidUpdate(prevProps: PropsType) {
    const {
      userData,
      userRightList,
      userPermissionList,
      setUserRights,
    } = this.props;

    if (
      userData &&
      Object.keys(userData).length > 0 &&
      userRightList &&
      userRightList?.length > 0 &&
      userPermissionList?.length === 0
    ) {
      setUserRights();
    }
  }

  render() {
    return (
      <Fragment>
        <ErrorBoundary></ErrorBoundary>
      </Fragment>
    );
  }
}

function mapStateToProps(state: ReduxStateType) {
  return {
    userData: state.auth?.userData,
    userRightList: state.auth?.userRightList,
    userPermissionList: state.shared?.userPermissionList,
  };
}

const mapDispatch = {
  getUserByToken,
  getUserRights,
  setUserRights,
};

export default connect<StoreProps, DispatchProps>(
  mapStateToProps,
  mapDispatch
)(App);

我在 index.tsx 方法的 render 文件中遇到错误。我是 TypeScript 的新手。如果有人能告诉我我哪里做错了,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

您有两个不同的包,它们可能将自己的 props 注入到您的组件中:Redux 和 React Router。

当您将组件定义为 class App extends Component<PropsType, any> 时,它期望接收 PropsType 作为其 props。

type PropsType = RouteComponentProps & StoreProps & DispatchProps;

它需要接收您列为道具的所有三个接口。 StorePropsDispatchProps 是 Redux connect 高阶组件注入的,这些没问题。您的错误消息告诉您缺少的道具是 historylocationmatch。这些是 RouteComponentProps 的属性。

现在您的组件实际上并没有使用任何 Router 道具,因此最简单的解决方案就是从 RouteComponentProps 中删除 PropsType。把它放在那里,你就要求这些道具存在。

如果您想真正包含 RouteComponentProps,则需要在 index.tsx 中进行更改。您已将 App 包裹在 BrowserRouter 中,但它实际上并没有做任何事情,因为您尚未定义任何路由。您需要一个包含 Switch 组件的 Route 组件。如果在 App 组件中加载 Route,则将注入 RouteComponentProps

查看 React Router docs 以了解如何设置多条路线。这将始终加载 App(因此没有变化),但现在它将获得所需的道具。有多种方法可以为 Route 声明组件,但您希望使用 component proprender prop 而不是子代,因为它们允许打字稿知道包含路由器道具。

ReactDOM.render(
  <Provider store={reduxStore.store}>
    <BrowserRouter>
      <Switch>
        <Route
          path="/"
          component={App}
        />
      </Switch>
    </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);