在Redirect组件(React.js)中传递道具无法正常工作

时间:2018-10-11 14:18:32

标签: reactjs redirect react-router

我正在通过一个练习应用程序来结识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>
    );
  }
}

但是在这种情况下,我只能完成重定向,而UI中不会显示任何消息。

我正在尝试将道具传递给home"/",所以如果有人从TeamPage 提出了建议。我的App组件中的Route会像往常一样用该消息进行响应。

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) }
      }}
    />
  );
}

可以做到吗?

谢谢!

更新10月11日下午2:56

因此,根据Hannad的深刻见解,我更新了App componentTeamPage component并创建了一条捕获所有ErrorPage路由。我现在需要做的是更新Teams.js文件,因为当我尝试转到http://localhost:3000/teams/foo时出现以下错误:

enter image description here

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>
    );
  }
}

1 个答案:

答案 0 :(得分:2)

还有另一种进行404重定向的方法。我会建议。因为它拥有更多控制权。.

定义需要简单参数的错误组件。

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 path="/error/:errortype" exact component={ErrorPage} />

          </Switch>
        </div>
      </Router>
    );
  }
}

//您的重定向逻辑

const { loading, teamNames, articles } = this.state;
const { match }                        = this.props;

const { teamId } = match.params;

if (loading === false && teamNames.includes(teamId) === false) {
  return (
    <Redirect
      to={'/error/404'}
    />
  );
}

// ErrorPage组件

const ErorPage = ({match: { params:{ errortype } }})=>(
  // have your logic for different templates for different types of errors.
  // ex.
  <div>
    {
      errortype === 404 ?
      <div>you got a 404</div> :
      <div>sone generic message</div>
      // this logic can change with respect to your app.
    }
  </div>
)