路线未渲染组件

时间:2020-07-02 03:47:13

标签: javascript reactjs

我正在尝试在以下代码中使用React Router,并在单击按钮时渲染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);

应用程序呈现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;

1 个答案:

答案 0 :(得分:1)

问题

<Route exact path="/student/courses" component={CourseList} />表示,当您推送到新路线时,它不再匹配,因此不再呈现CourseList,这意味着"/student/courses/:course"的路线也未安装并且不会渲染任何东西。

解决方案

在给出路径定义CourseDetail的情况下,

course将获得"/student/courses/:course"作为路线匹配参数的支持。

props.match.params.course

继续,然后在主路由器中定义其路由。移除exact属性,并在{em> {em> }之前定义更具体的路径,因为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,将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组件代码,我可以提供更准确的建议,则以上只是一个粗略估计。