reactjs - Tipul '{}' nu are următoarele proprietăți din tip


În proiectul meu React primesc următoarea eroare pentru componenta mea 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)

Următorul este codul fișierului meu 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();

și următorul este codul fișierului meu 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);

Primesc eroarea în fișierul index.tsx în metoda render. Sunt nou în TypeScript. Aș aprecia foarte mult dacă cineva mi-ar putea spune unde greșesc.

Răspuns #1

Ai două pachete diferite care ar putea injecta propriile lor props în componenta ta: Redux și React Router.

Când îți definești componenta ca class App extends Component<PropsType, any>, aceasta se așteaptă să primească PropsType ca proprietăți ale sale.

type PropsType = RouteComponentProps & StoreProps & DispatchProps;

Trebuie să primească toate cele trei interfețe pe care le-ai listat ca props. StoreProps și DispatchProps sunt cele care sunt injectate de componenta de ordin superior connect din Redux, și acestea sunt în regulă. Mesajul tău de eroare îți spune că props-urile lipsă sunt history, location și match. Acestea sunt proprietățile lui RouteComponentProps.

În acest moment, componenta ta nu folosește de fapt niciunul dintre prop-urile Router, așa că cea mai simplă soluție este să elimini RouteComponentProps din PropsType. Punându-l acolo, soliciți ca acele prop-uri să fie prezente.

Dacă vrei să incluzi efectiv RouteComponentProps, atunci trebuie făcute modificări în index.tsx. Ai înfășurat App într-un BrowserRouter, dar acesta nu face de fapt nimic pentru că nu ai definit niciun traseu. Ai nevoie de un component Switch cu componente Route în interiorul său. Dacă App este încărcat într-un component Route, atunci RouteComponentProps vor fi injectate.

Verifică documentația React Router pentru a vedea cum să configurezi multiple rute. Aceasta va încărca întotdeauna App (deci nicio schimbare), dar acum va primi props-urile necesare. Există multiple moduri de a declara componenta pentru o Rută, dar vrei să folosești prop-ul component sau render în loc de children deoarece acestea permit TypeScript să știe că props-urile routerului sunt incluse.

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