【问题标题】:Route not rendering component路由不渲染组件
【发布时间】:2020-10-22 14:23:19
【问题描述】:

我正在尝试在以下代码中使用反应路由器,并在按钮单击时呈现 CourseDetail 组件。但是,没有呈现任何内容(只是转到相应的 URL)。

我不想把它和我所有的其他路由一起放在我的 App.js 文件中,因为我想在这个特定的父组件中使用道具。任何帮助表示赞赏!

另外编辑:${match.url} 给出 /student/courses

import {
  BrowserRouter,
  Route,
  Switch,
  withRouter,
  Link,
} from "react-router-dom";
import { Card, Button } from "react-bootstrap";
import "./style.css";
import CourseDetail from "./CourseDetail";

class CourseItem extends React.Component {
  render() {
    const { course, match } = this.props;
    return (
      <div>
        <Card style={{ width: "18rem" }}>
          <Card.Body>
            <Card.Title>
              {course.subject} {course.code}: {course.name}
            </Card.Title>
            <Button variant="primary">
              <Link to={`${match.url}/${course.subject}${course.code}`}>
                Access Course
              </Link>
            </Button>
          </Card.Body>
        </Card>
        <BrowserRouter>
          <Switch>
            <Route
              exact
              path="/student/courses/:course"
              render={(props) => <CourseDetail {...props} course={course} />}
            />
          </Switch>
        </BrowserRouter>
      </div>
    );
  }
}

export default withRouter(CourseItem);

课程项目由课程列表呈现:

import React from "react";
import { withRouter } from "react-router-dom";
import Header from "../../../components/Header";
import CourseItem from "./CourseItem";
import { CardDeck, Container } from "react-bootstrap";
import axios from "axios";

class CourseList extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      courses: [],
      isLoading: false,
      error: "",
    };
  }


  render() {
    const { courses } = this.state;
    return (
      <div className="course-list">
        <Header title="Courses & Labs" />
        <Container>
          <CardDeck>
            {courses &&
              courses.map((course) => {
                return <CourseItem course={course} />;
              })}
          </CardDeck>
        </Container>
      </div>
    );
  }
}

export default withRouter(CourseList);

App 渲染 CourseList:

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import data from "./data.json";
import Navigation from "./components/Navigation";
import Footer from "./components/Footer";
import Home from "./pages/Home";
import About from "./pages/About";
import Research from "./pages/Research";
import Publications from "./pages/Publications";
import HallOfFame from "./pages/HallOfFame";
import EvaluationList from "./pages/Student/TAEvaluations/EvaluationList";
import CourseList from "./pages/Student/Courses/CourseList";
import CourseDetail from "./pages/Student/Courses/CourseDetail";
import CourseEditorList from "./pages/Prof/CourseEditor/CourseEditorList";
import CourseEditorDetail from "./pages/Prof/CourseEditor/CourseEditorDetail";
import EvaluationEditorList from "./pages/Prof/EvaluationEditor/EvaluationEditorList";
import EvaluationEditorDetail from "./pages/Prof/EvaluationEditor/EvaluationEditorDetail";
import ReportList from "./pages/Prof/ReportEditor/ReportList";
import ReportDetail from "./pages/Prof/ReportEditor/ReportDetail";

class App extends React.Component {
  render() {
    const mockCourses = data.Courses;

    return (
      <div className="App">
        <BrowserRouter>
          <Navigation />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
            <Route path="/research" component={Research} />
            <Route path="/publications" component={Publications} />
            <Route path="/halloffame" component={HallOfFame} />
 
            <Route exact path="/student/courses" component={CourseList} />
          </Switch>
        </BrowserRouter>
        <Footer />
      </div>
    );
  }
}

export default App;

【问题讨论】:

  • 您能否分享您的主路由器,即渲染此组件的路由器CourseItem,CourseItem 的路由可能与"/student/courses/:course" 不同,因此永远不会匹配。您的评论“${match.url}给/student/courses”也暗示/确认了这一点。
  • 刚刚做了 - 让我知道你的想法!
  • 是的,正如我所期望的那样。 &lt;Route exact path="/student/courses" component={CourseList} /&gt; 意味着一旦你推送到一条新路线,它就不再匹配,因此不再渲染CourseList,这意味着另一条路线也没有安装,也不会渲染任何东西。 CourseDetail 将收到 course 作为路由匹配参数的道具,如果您还可以使用 CourseDetail 的代码更新问题,我可以提供一个很好的重构建议。

标签: javascript reactjs


【解决方案1】:

问题

&lt;Route exact path="/student/courses" component={CourseList} /&gt; 意味着一旦您推送到新路由,它就不再匹配,因此不再渲染 CourseList,这意味着 "/student/courses/:course" 的路由也没有安装并且不会渲染任何东西。

解决方案

CourseDetail 将接收course 作为路径匹配参数的道具,给定路径定义"/student/courses/:course"。

props.match.params.course

继续并在主路由器中定义其路由。删除exact 属性并定义更具体的路径之前因为Switch 只返回第一个匹配项。

class App extends React.Component {
  render() {
    const mockCourses = data.Courses;

    return (
      <div className="App">
        <BrowserRouter>
          <Navigation />
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
            <Route path="/research" component={Research} />
            <Route path="/publications" component={Publications} />
            <Route path="/halloffame" component={HallOfFame} />
 
            <Route
              path="/student/courses/:course"
              component={CourseDetail}
            />
    
            <Route path="/student/courses" component={CourseList} />
          </Switch>
        </BrowserRouter>
        <Footer />
      </div>
    );
  }
}

从CourseItem 中删除路由器,主路由器现在可以处理该路由/路径。

class CourseItem extends React.Component {
  render() {
    const { course, match } = this.props;
    return (
      <div>
        <Card style={{ width: "18rem" }}>
          <Card.Body>
            <Card.Title>
              {course.subject} {course.code}: {course.name}
            </Card.Title>
            <Button variant="primary">
              <Link to={`${match.url}/${course.subject}${course.code}`}>
                Access Course
              </Link>
            </Button>
          </Card.Body>
        </Card>
      </div>
    );
  }
}

重构 CourseDetail 以从匹配参数与 props 根中提取 course。实现适当的生命周期函数来处理 course 属性值更新,例如,如果用户直接从 "/student/courses/ABC" 转到 "/student/courses/DEF" 而没有先转到不同的路由/路径。

class CourseDetail extends Component {

  ...

  componentDidMount() {
    const {
      match: {
        params: {
          course,
        },
      },
    } = this.props;
    // use `course` to load the correct course content
    
    ...
  }

  ...

  componentDidUpdate(prevProps) {
    const {
      match: {
        params: {
          course,
        },
      },
    } = this.props;

    const {
      match: {
        params: {
          course: prevCourse,
        },
      },
    } = prevProps;

    if (prevCourse !== course) {
      // use `course` to reload the correct course content
    }
    
    ...
  }
  
  ...
}

注意:如果你能提供你的CourseDetail组件代码我可以提供更准确的建议,以上只是粗略的估计。

【讨论】:

    【解决方案2】:

    在

    react-router-Dom
    

    6,组件被元素替换,所以代替这个:

     <Route path="/" component="App" />
    

    使用这个:

    <Route path="/" element={<App/>} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-25
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 2020-04-07
      • 2021-01-18
      相关资源
      最近更新 更多