【问题标题】:Passing props in the Redirect component (React.js) not working as expected在重定向组件 (React.js) 中传递道具未按预期工作
【发布时间】:2019-03-16 16:13:16
【问题描述】:

我正在通过一个练习应用程序来熟悉React-Router

在我的 App 组件中,我有一个 Route 可以为 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 并创建了一个 catch all 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>
    );
  }
}

【问题讨论】:

    标签: reactjs redirect react-router


    【解决方案1】:

    还有另一种方法可以进行 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'}
        />
      );
    }
    

    // 错误页面组件

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

    【讨论】:

    • 我很快就会尝试一下,我会让你知道我的发现!谢谢!
    • 欢迎:D。我在stackoverflow上很活跃..在这里发表评论,我会回复:D
    • 很抱歉打乱了您的回答,它很棒,我只是要更新我的问题。我在上面收到错误。基本上我知道必须在Teams.js 组件中实现错误处理,但我不确定在哪里!!!
    • 是的,我在想那个编辑是关于什么的。更新你的问题,我会看看
    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多