Реагировать на Typescript - Как добавить типы в location.state при передаче в маршрут - PullRequest
1 голос
/ 21 февраля 2020

Я получаю сообщение об ошибке, когда я передаю реквизиты реакции-маршрутизатора, отправленные компоненту в маршруте, потому что у меня есть указанное c состояние, что я передаю этот компонент, но ошибка отображается в моем маршруте.

enter image description here

Вот код маршрута:

<Route
    exact
    path='/flipltimeline'
    render={props => <FliplTimeline {...props} />

В другом компоненте я называю это ниже

props.history.push(`/flipltimeline`, {
      Approval: singleFliplApprovals,
      InvestigationID,
      Unit: unit,
      Cost: cost
    });

Вот код для компонента. Я наконец получил Typescript для компиляции, но мне пришлось объединить LocationState & TimelineState, чтобы заставить это работать. Но теперь Typescript выдает приведенный выше скриншот, когда я отправляю реквизиты в свой компонент FliplTimeline. Кто-нибудь есть и идея, как это исправить?

history.tsx

import { createBrowserHistory } from 'history';

let baseNameProd = '';

if (process.env.NODE_ENV !== 'production') {
  console.log('Looks like we are in development mode!');
  baseNameProd = '';
} else {
  baseNameProd = '/flipl';
}

const customHistory = createBrowserHistory({
  basename: baseNameProd
});

export default customHistory;

FliplTimeline.tsx

import * as React from 'react';
import { History, LocationState } from 'history';

interface FliplTimelineLocationState {
  Approval: any;
  InvestigationID: number;
  Unit: string;
  Cost: number;
}

interface TimelineState{
  state: FliplTimelineLocationState;
}

interface Props {
  history: History;
  location: LocationState & TimelineState;
}

function FliplTimeline(props: Props) {
  return (
    <ModuleTemplate title='Status Timeline' subtitle=''>
      <FliplTimelineJumbotron className='bg-primary-darker shadow-4 line-height-serif-4'>
        <div className='grid-row'>
          <div className='grid-col-4'>
            <span
              className='font-mono-2xl text-white'
              style={{
                verticalAlign: 'middle'
              }}
            >
              FLIPL{' '}
            </span>
            <span
              className='font-mono-xl text-gold'
              style={{
                verticalAlign: 'middle'
              }}
            >
              {props.location.state.InvestigationID}
            </span>

Обновление: добавлен мой файл history.tsx, в котором я создал свою собственную историю для React-Router. Также добавлено в операторах импорта.

Обновление: попытался изменить мой компонент FliplTimeline, чтобы иметь этот интерфейс

import { RouteComponentProps } from 'react-router-dom'

function FliplTimeline(props: RouteComponentProps ) {

Я получаю 2 ошибки. Первый - это тот, который говорит, что форма реквизита неправильная. Идеи? tserror

Обновление: я наконец смог получить правильное объявление реквизита для моего компонента.

import { RouteComponentProps } from 'react-router-dom';

interface FliplTimelineLocationState {
  Approval: any;
  InvestigationID: number;
  Unit: string;
  Cost: number;
}

function FliplTimeline(
  props: RouteComponentProps<{}, any, FliplTimelineLocationState | any>
)

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Мне удалось заставить его работать.

import { RouteComponentProps } from 'react-router-dom';

interface FliplTimelineLocationState {
  Approval: any;
  InvestigationID: number;
  Unit: string;
  Cost: number;
}

function FliplTimeline(
  props: RouteComponentProps<{}, any, FliplTimelineLocationState | any>
)
0 голосов
/ 21 февраля 2020

Используйте RouteComponentProps и скормите ему соответствующие типы для его обобщенного c. Эта статья охватывает совсем немного: Как использовать React Router в Typescript .

Использование React Router с TypeScript почти требует заполнения дженериков, которые есть в React Router. В противном случае не хватает контекста для определения типов всего. Сравните с моим примером ниже. Я использую useHistory и заполняю его типом, который я хочу сделать доступным. Вероятно, это будет FliplTimelineLocationState, так что свойство state history будет иметь тип FliplTimelineLocationState.

import React, {MouseEventHandler} from "react";
import {Route, RouteComponentProps, StaticContext, useHistory} from "react-router";
import {BrowserRouter, Link} from "react-router-dom";

interface IMyScreenRouteParams {
    foo: string;
}

// You don't have to extend, you could just use StaticContext
interface IMyStaticContext extends StaticContext {
    bar: string;
}

interface IHistory {
    fizz: string;
}

const Nav = () => {
    const history = useHistory<IHistory>();

    const clickHanlder: MouseEventHandler = () => {
        history.push("/my-screen", {
            fizz: "you said fizz"
        });
    };

    return (
        <nav>
            <ul>
                <li><Link to="/">Home</Link></li>
                <li><Link to="/my-screen">My Screen</Link></li>
                <li><button onClick={clickHanlder}>My Screen with state</button></li>
                <li><Link to="/my-screen?q=hello">My Screen with query</Link></li>
                <li><Link to="/my-screen/bob">My Screen using match</Link></li>
            </ul>
            <div>
                <button onClick={() => history.goBack()}>Back</button>
                <button onClick={() => history.push("/")}>Home</button>
                <button onClick={() => history.goForward()}>Forward</button>
            </div>
        </nav>
    );
};

const MyScreen = ({
    location,
    match,
    history,
    staticContext
}: RouteComponentProps<IMyScreenRouteParams, IMyStaticContext, IHistory>) => (
    <div>
        <section>
            <h2>Location</h2>
            <p><code>location</code> has <code>IHistory</code> props.</p>
            <pre><code>{JSON.stringify(location, null, 4)}

Соответствие

match имеет IMyScreenRouteParams реквизитов.

{JSON.stringify(match, null, 4)}

История

history имеет IHistory реквизитов.

{JSON.stringify(history, null, 4)}

Stati c Context

staticContext имеет IMyStaticContext реквизитов или любой другой stati c контекст вашего маршрутизатора.

Это для &lt;StaticRouter/&gt;.

{JSON.stringify(staticContext, null, 4)}
); const Router = () => (
(
Нажмите что-нибудь в &lt;nav/&gt;
)} />
); Маршрутизатор экспорта по умолчанию;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...