Я работаю через приложение для практики, чтобы познакомиться с React-Router
В моем App
компоненте у меня есть Маршрут, который действует как способ позволить себе 404's
class App extends Component {
render() {
return (
<Router>
<div>
<Navbar />
<Switch>
<Route path="/" exact component={Home} />
<Route path="/players" component={Players} />
<Route path="/teams" component={Teams} />
{/* params should be last Route as it would match players and teams */}
<Route path="/:teamId" exact component={TeamPage} />
<Route
render={({ location }) => (
<h1 className="text-center">
Sorry, we couldn't find {location.pathname.substr(1)} <br />{" "}
404: page not found.
</h1>
)}
/>
</Switch>
</div>
</Router>
);
}
}
Это прекрасно работает.
Однако у меня есть другой компонент TeamPage
, который по сути имеет тот же механизм.
import React, { Component } from "react";
import { Redirect, Link } from "react-router-dom";
import { getTeamNames, getTeamsArticles } from "../api";
import TeamLogo from "./TeamLogo";
import Team from "./Team";
import slug from "slug";
export default class TeamPage extends Component {
state = {
loading : true,
teamNames: {},
articles : []
};
componentDidMount() {
Promise.all([
getTeamNames(),
getTeamsArticles(this.props.match.params.teamId)
]).then(([teamNames, articles]) => {
this.setState(() => ({
teamNames,
articles,
loading: false
}));
});
}
render() {
const { loading, teamNames, articles } = this.state;
const { match } = this.props;
const { teamId } = match.params;
if (loading === false && teamNames.includes(teamId) === false) {
return (
<Redirect
to={{
pathname: "/",
location: { location: window.location.pathname.substr(1) }
}}
/>
);
}
return (
<div>
<Team id={teamId}>
{team =>
team === null ? (
<h1>LOADING</h1>
) : (
<div className="panel">
<TeamLogo id={teamId} />
<h1 className="medium-header">{team.name}</h1>
<h4 style={{ margin: 5 }}>
<Link
style = {{ cursor: "pointer" }}
to = {{ pathname: "/players", search: `?teamId=${teamId}` }}
>
View Roster
</Link>
</h4>
<h4>Championships</h4>
<ul className="championships">
{team.championships.map(ship => (
<li key={ship}>{ship}</li>
))}
</ul>
<ul className="info-list row" style={{ width: "100%" }}>
<li>
Established
<div>{team.established}</div>
</li>
<li>
Manager
<div>{team.manager}</div>
</li>
<li>
Coach
<div>{team.coach}</div>
</li>
<li>
Record
<div>
{team.wins}-{team.losses}
</div>
</li>
</ul>
<h2 className="header">Articles</h2>
<ul className="articles">
{articles.map(article => (
<li key={article.id}>
<Link to={`${match.url}/articles/${slug(article.title)}`}>
<h4 className="article-title">{article.title}</h4>
<div className="article-date">
{article.date.toLocaleDateString()}
</div>
</Link>
</li>
))}
</ul>
</div>
)
}
</Team>
</div>
);
}
}
Нов этом случае я могу выполнить перенаправление только без сообщения в пользовательском интерфейсе.
Я пытаюсь передать реквизиты на home
или "/"
, поэтому, если кто-то сделал , то изTeamPage
.Маршрут в моем App
компоненте будет отвечать этим сообщением, как обычно.
Выдержка из TeamPage:
const { loading, teamNames, articles } = this.state;
const { match } = this.props;
const { teamId } = match.params;
if (loading === false && teamNames.includes(teamId) === false) {
return (
<Redirect
to={{
pathname: "/",
location: { location: window.location.pathname.substr(1) }
}}
/>
);
}
Можно ли это сделать?
Спасибозаранее!
Обновление 11 октября 2:56 PM
Так, согласно великому пониманию Ханнада, я обновил свои App component
и TeamPage component
и создал перехват всех ErrorPageмаршрут.Теперь мне нужно обновить файл Teams.js
, так как при попытке перейти на http://localhost:3000/teams/foo
я получаю следующую ошибку:
import React, { Component } from "react";
import { Redirect, Route, Link } from "react-router-dom";
import Sidebar from "./Sidebar";
import { getTeamNames } from "../api";
import TeamLogo from "./TeamLogo";
import Team from "./Team";
export default class Teams extends Component {
state = {
teamNames: [],
loading : true
};
componentDidMount() {
getTeamNames().then(teamNames => {
this.setState(() => ({
loading: false,
teamNames
}));
});
}
render() {
const { loading, teamNames } = this.state;
const { location, match } = this.props;
return (
<div className="container two-column">
<Sidebar
loading = {loading}
title = "Teams"
list = {teamNames}
{...this.props}
/>
{loading === false &&
(location.pathname === "/teams" || location.pathname === "/teams/") ? (
<div className="sidebar-instruction">Select a Team</div>
) : null}
<Route
path = {`${match.url}/:teamId`}
render = {({ match }) => (
<div className="panel">
<Team id={match.params.teamId}>
{team =>
team === null ? (
<h1>Loading</h1>
) : (
<div style={{ width: "100%" }}>
<TeamLogo id={team.id} className="center" />
<h1 className="medium-header">{team.name}</h1>
<ul className="info-list row">
<li>
Established
<div>{team.established}</div>
</li>
<li>
Manager
<div>{team.manager}</div>
</li>
<li>
Coach
<div>{team.coach}</div>
</li>
</ul>
<Link
className = "center btn-main"
to = {`/${match.params.teamId}`}
>
{team.name} Team Page
</Link>
</div>
)
}
</Team>
</div>
)}
/>
</div>
);
}
}