反应路由器4`链接`组件只改变URL和不更新路由
我遇到了react-router-dom Link
组件只能更改URL和不更新路由的问题。反应路由器4`链接`组件只改变URL和不更新路由
它可以从/courses -> /courses/<course-slug>
精细链接,然后/courses/<course-slug> -> /lessons/<lesson-slug>
但是它链接到其他课程如与我有问题从/lessons/<lesson-slug> -> /lessons/<different-lesson-slug>
它似乎只更新LessonsList
组件并更新URL但不更新路线/内容或父母Lesson
。
我已经确保将匹配,位置道具下放到组件,因为它与更新阻止有关 - https://reacttraining.com/react-router/web/guides/dealing-with-update-blocking但它似乎仍然不起作用。
我看不到我要去哪里错了,它应该相对简单。
这与我如何设置我的路线或具有相同路线有什么关系?
这里是我的依赖和代码,任何点在正确的方向将不胜感激。
"dependencies": {
"axios": "^0.16.2",
"prop-types": "^15.5.10",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router-dom": "^4.1.2"
}
index.js
import css from '../css/index.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './components/App';
ReactDOM.render(
<Router>
<App />
</Router>
, document.getElementById('app'));
应用/ index.js
import React, { Component } from 'react';
import Header from '../Header';
import Main from '../Main';
import Footer from '../Footer';
class App extends Component {
render() {
return(
<div>
<Header />
<Main />
<Footer />
</div>
);
}
}
export default App;
主/ index.js
import React, { Component } from 'react';
import { Route, Link, Switch } from 'react-router-dom';
import Home from '../Home';
import Courses from '../Courses';
import Course from '../Course';
import Lessons from '../Lessons';
import Lesson from '../Lesson';
class Main extends Component {
constructor(props) {
super(props);
}
render() {
return(
<div className="main">
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/courses/:course" component={Course}/>
<Route exact path="/courses" component={Courses}/>
<Route path="/lessons/:lesson" component={Lesson}/>
<Route exact path="/lessons" component={Lessons}/>
<Route render={() => (
<div>Not Found 404</div>
)}/>
</Switch>
</div>
);
}
}
export default Main;
吸取/ index.js
import React, { Component } from 'react';
import api from '../../utils/api';
import LessonsList from '../LessonsList';
import { Link } from 'react-router-dom';
class Lessons extends Component {
constructor(props) {
super(props);
this.state = {
lessons: null
};
}
componentDidMount() {
api.getAllLessons()
.then((lessons) => {
this.setState({
lessons: lessons
});
});
}
render() {
return(
<div className="lessons">
{!this.state.lessons ?
<div>Loading...</div>
:
<div>
<LessonsList
lessons={this.state.lessons}
{...this.props}
/>
</div>
}
</div>
);
}
}
export default Lessons;
课程/ index.js
import React, { Component } from 'react';
import api from '../../utils/api';
import LessonsList from '../LessonsList';
import { Link } from 'react-router-dom';
class Lesson extends Component {
constructor(props) {
super(props);
this.state = {
lesson: null
}
}
componentDidMount() {
api.getLesson(this.props.match.params.lesson)
.then((lesson) => {
this.setState({
lesson: lesson[0]
});
});
}
render() {
return(
<div className="lesson">
{!this.state.lesson ?
<div>Loading...</div>
:
<div>
<h3>Course title: {this.state.lesson.course.title}</h3>
<h1>Lesson: {this.state.lesson.title}</h1>
<h2>Other lessons from this course</h2>
<LessonsList
lessons={this.state.lesson.lessons}
{...this.props}
/>
</div>
}
</div>
);
}
}
export default Lesson;
LessonsList/index.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
function LessonsList(props) {
return(
<ul>
{props.lessons.map((lesson) => {
return(
<li key={lesson.id}>
<Link to={`/lessons/${lesson.slug}`}>{lesson.title}</Link>
</li>
);
})}
</ul>
);
}
LessonsList.propTypes = {
lessons: PropTypes.array.isRequired
}
export default LessonsList;
UPDATE:
下面是与componentWillReceiveProps
课程/索引更新组件.js
import React, { Component } from 'react';
import api from '../../utils/api';
import LessonsList from '../LessonsList';
import { Link } from 'react-router-dom';
class Lesson extends Component {
constructor(props) {
super(props);
this.state = {
lesson: null
}
}
componentDidMount() {
api.getLesson(this.props.match.params.lesson)
.then((lesson) => {
this.setState({
lesson: lesson[0]
});
});
}
componentWillReceiveProps(nextProps) {
if(this.props.match.params.lesson !== nextProps.match.params.lesson) {
api.getLesson(nextProps.match.params.lesson)
.then((lesson) => {
this.setState({
lesson: lesson[0]
});
});
}
}
render() {
return(
<div className="lesson">
{!this.state.lesson ?
<div>Loading...</div>
:
<div>
<h3>Course title: {this.state.lesson.course.title}</h3>
<h1>Lesson: {this.state.lesson.title}</h1>
<h2>Other lessons from this course</h2>
<LessonsList
lessons={this.state.lesson.lessons}
{...this.props}
/>
</div>
}
</div>
);
}
}
export default Lesson;
您的<Lesson />
组件仅在componentDidMount
生命周期挂钩期间设置课程。如果您正在上课并且您更改了slu,,它不会导致组件重新装入。您可以使用componentWillReceiveProps
生命周期挂钩来完成您的工作。
componentWillReceiveProps(nextProps) {
api.getLesson(nextProps.match.params.lesson)
.then((lesson) => {
this.setState({
lesson: lesson[0]
});
});
}
此问题与componentDidMount事件有关。当你改变课程时不会被解雇。所以你应该使用componentDidUpdate来更改课程。
componentDidUpdate() {
if (this.props.match.params.lesson !== this.state.lesson.slug)
api.getLesson(this.props.match.params.lesson)
.then((lesson) => {
this.setState({
lesson: lesson[0]
});
});
}
}
为什么要等到更新后才使用setState? –
我们也可以使用componentWillReceiveProps,它并不重要,无论如何都会将数据传递到状态 –
使用componentDidUpdate钩子将导致无关渲染。这不是说这是世界上最糟糕的事情,而只是没有必要。 –
这是我需要的正确方向的一点!谢谢。虽然我需要通过更新的道具来获得新的slu。。 – user3178098