Как мне go о создании реагирующего маршрутизатора в Typescript? - PullRequest
2 голосов
/ 01 августа 2020

В нормальном проекте реакции мой маршрутизатор будет выглядеть так

Я бы обернул свое приложение в компонент, а затем получил бы это

<Switch>

<Route path="/login" render={(props) => <LoginPage login={this.login} authed={this.state.isAuthenticated} {...props} />} />
<Route path="/" render={(props) => this.props.history.push("/login")} />

</Switch>

Но я не знаю, как чтобы смоделировать нечто подобное в машинописном тексте. В настоящее время у меня есть это

const App: React.FunctionComponent = () => {
  return (
    <Router>
      <div className="main-content">
        <div>
          <Switch>
            <Route exactly component={Main} exact pattern="/" />
            <Route exactly component={Count} exact pattern="/count" />
          </Switch>
        </div>
      </div>
    </Router>
  );
};

, но он всегда перенаправляет на основной компонент. Как я могу сделать, чтобы неопределенный маршрут, такой как / randomroute, перенаправлялся на «/», и как мне заставить работать альтернативный маршрут / счетчик?

РЕДАКТИРОВАТЬ: Я немного продвинулся

import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";

interface ChildComponentProps extends RouteProps {
  /* other props for ChildComponent */
}

const App: React.FunctionComponent<ChildComponentProps> = (props) => {
  return (
    <Router>
      <div className="main-content">
        <div>
          <Switch>
            <Route exactly component={Main} exact path="/" />
            <Route exactly component={Count} exact path="/count" />
            <Route pattern ="/" render={() => props.history.push("/") } />
          </Switch>
        </div>
      </div>
    </Router>
  );
};

export default App;

Проблема теперь в том, что история находится внутри интерфейса RouteComponentProps, в то время как интерфейс RouteProps содержит рендеринг, и я не могу использовать их одновременно, поэтому я немного потерялся

EDIT2: Пробуем это

   interface RenderProps extends RouteProps {
  /* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {

}

const App: React.FunctionComponent<HistoryProps & RenderProps>

Получение при рендеринге

Ожидаемый тип происходит от свойства 'render', которое здесь объявлено в типе 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly & Readonly <...>'

Когда предположительно этот интерфейс импортирован

Edit4:

Я сделал это

import React from "react";
import { BrowserRouter as Router, Route, Switch, RouteComponentProps, RouteProps, withRouter  } from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count"
import "./App.css";

interface RenderProps extends RouteProps {
  /* other props for ChildComponent */
}
interface HistoryProps extends RouteComponentProps {
    
}

const App: React.FunctionComponent<RenderProps & HistoryProps> = (props) => {
  return (
      <div className="main-content">
        <div>
          <Switch>
            <Route exactly component={Main} exact path="/" />
            <Route exactly component={Count} exact path="/count" />
            <Route path ="/" {...props.history.push("/")} />
          </Switch>
        </div>
      </div>
  );
};


export default withRouter(App);

И оберните компонент приложения в файл index.tsx в (browserouter)

Теперь я получаю

Ошибка: превышена максимальная глубина обновления. Это может произойти, когда компонент многократно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы

Из-за props.history.pu sh

1 Ответ

0 голосов
/ 02 августа 2020

В итоге я сделал это, но жду лучших ответов

import React from "react";
import { Route, Switch, RouteComponentProps, withRouter} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import Redirector from "./components/Redirect"
import "./App.css";


interface HistoryProps extends RouteComponentProps {
    
}


const App: React.FunctionComponent<HistoryProps> = (props) => {
  return (
      <div className="main-content">
        <div>
          <Switch>
            <Route exactly component={Main} exact path="/" />
            <Route exactly component={Count} exact path="/count" />
            <Route path ="/" exactly component={Redirector}/>
          </Switch>
        </div>
      </div>
  );
};


export default withRouter(App);

Redirect.tsx

import * as React from "react";
import { Redirect   } from "react-router-dom";

const Redirector: React.FunctionComponent = () => {
  
  return <Redirect to='/'/>;
};

export default Redirector

EDIT2: Вероятно, лучший подход

import React from "react";
import { Route, Switch, withRouter, Redirect} from "react-router-dom";
import Main from "./components/Main";
import Count from "./components/Count";
import "./App.css";


const App: React.FunctionComponent = () => {
  const renderFor404Routes = () => (<Redirect to='/'/>);
  return (
      <div className="main-content">
        <div>
          <Switch>
            <Route exactly component={Main} exact path="/" />
            <Route exactly component={Count} exact path="/count" />
            <Route path ="/" exactly component={renderFor404Routes}/>
          </Switch>
        </div>
      </div>
  );
};

export default withRouter(App);
...