admin管理员组文章数量:1387354
I'm trying to use react router in the following code, and render the CourseDetail ponent on button click. However, nothing renders (just goes to the appropriate URL).
I don't want to put it in my App.js file with all my other routes, as I want to use the props in this specific parent ponent. Any help is appreciated!
Also edit: ${match.url} gives /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);
Course Item is rendered by Course List:
import React from "react";
import { withRouter } from "react-router-dom";
import Header from "../../../ponents/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 renders CourseList:
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import data from "./data.json";
import Navigation from "./ponents/Navigation";
import Footer from "./ponents/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="/" ponent={Home} />
<Route path="/about" ponent={About} />
<Route path="/research" ponent={Research} />
<Route path="/publications" ponent={Publications} />
<Route path="/halloffame" ponent={HallOfFame} />
<Route exact path="/student/courses" ponent={CourseList} />
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
}
export default App;
I'm trying to use react router in the following code, and render the CourseDetail ponent on button click. However, nothing renders (just goes to the appropriate URL).
I don't want to put it in my App.js file with all my other routes, as I want to use the props in this specific parent ponent. Any help is appreciated!
Also edit: ${match.url} gives /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);
Course Item is rendered by Course List:
import React from "react";
import { withRouter } from "react-router-dom";
import Header from "../../../ponents/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 renders CourseList:
import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import data from "./data.json";
import Navigation from "./ponents/Navigation";
import Footer from "./ponents/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="/" ponent={Home} />
<Route path="/about" ponent={About} />
<Route path="/research" ponent={Research} />
<Route path="/publications" ponent={Publications} />
<Route path="/halloffame" ponent={HallOfFame} />
<Route exact path="/student/courses" ponent={CourseList} />
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
}
export default App;
Share
Improve this question
edited Jul 2, 2020 at 4:18
turkr
asked Jul 2, 2020 at 3:47
turkrturkr
432 silver badges8 bronze badges
3
-
Can you share your main router, the one that is rendering this ponent,
CourseItem
, chances areCourseItem
is on a different route than"/student/courses/:course"
and thus won't match, ever. Your ment "${match.url} gives /student/courses" also implies/confirms this. – Drew Reese Commented Jul 2, 2020 at 4:09 - Just did - let me know what you think! – turkr Commented Jul 2, 2020 at 4:19
-
Yes, precisely as I expected to see.
<Route exact path="/student/courses" ponent={CourseList} />
means as soon as you push to a new route it no longer matches and thus doesn't renderCourseList
anymore which means the other route also isn't mounted and won't render anything.CourseDetail
will receivecourse
as a prop off the route's match params, if you can also update question withCourseDetail
's code I can provide a good refactoring suggestion. – Drew Reese Commented Jul 2, 2020 at 4:59
3 Answers
Reset to default 3Issue
<Route exact path="/student/courses" ponent={CourseList} />
means as soon as you push to a new route it no longer matches and thus doesn't render CourseList
anymore which means the route for "/student/courses/:course"
also isn't mounted and won't render anything.
Solution
CourseDetail
will receive course
as a prop off the route's match params given the path definition "/student/courses/:course"
.
props.match.params.course
Go ahead and define its route in the main router. Remove the exact
prop and define the more specific path before the less specific path as the Switch
returns only the first match.
class App extends React.Component {
render() {
const mockCourses = data.Courses;
return (
<div className="App">
<BrowserRouter>
<Navigation />
<Switch>
<Route exact path="/" ponent={Home} />
<Route path="/about" ponent={About} />
<Route path="/research" ponent={Research} />
<Route path="/publications" ponent={Publications} />
<Route path="/halloffame" ponent={HallOfFame} />
<Route
path="/student/courses/:course"
ponent={CourseDetail}
/>
<Route path="/student/courses" ponent={CourseList} />
</Switch>
</BrowserRouter>
<Footer />
</div>
);
}
}
Remove the router from CourseItem
, the main router can now handle that route/path.
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>
);
}
}
Refactor CourseDetail
to pull the course
from the match params versus props root. Implement the appropriate lifecycle functions to handle course
prop value updating, for example, if user goes from "/student/courses/ABC"
to "/student/courses/DEF"
directly without first going to a different route/path.
class CourseDetail extends Component {
...
ponentDidMount() {
const {
match: {
params: {
course,
},
},
} = this.props;
// use `course` to load the correct course content
...
}
...
ponentDidUpdate(prevProps) {
const {
match: {
params: {
course,
},
},
} = this.props;
const {
match: {
params: {
course: prevCourse,
},
},
} = prevProps;
if (prevCourse !== course) {
// use `course` to reload the correct course content
}
...
}
...
}
Note: if you can provide your CourseDetail
ponent code I can provide a more accurate suggestion, the above is just a rough estimate.
in react-router-Dom 6, ponent is replaced by element, so instead of this:
<Route path="/" ponent="App" />
use this:
<Route path="/" element={<App/>} />
What worked for me is:
I enclosed all my 'Route' ponents into one 'Routes' ponent. They are all imported from 'react-router-dom'
Also ensure you use the 'element' props to link to a ponent.
import "./App.css"; import { BrowserRouter, Route, Routes } from "react-router-dom"; import Header from "./ponents/Header"; import Homepage from "./pages/Homepage"; import Coinpage from "./pages/Coinpage"; import { makeStyles } from "@material-ui/core"; function App() { return ( <BrowserRouter> <div> <Header /> <Routes> <Route path="/" element={<Homepage/>} exact /> <Route path="/coins/:id" element={<Coinpage/>} /> </Routes> </div> </BrowserRouter> ); }
本文标签: javascriptRoute not rendering componentStack Overflow
版权声明:本文标题:javascript - Route not rendering component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744535221a2611273.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论