反应路由器4`链接`组件只改变URL和不更新路由

反应路由器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] 
     }); 
    }); 
} 
+0

这是我需要的正确方向的一点!谢谢。虽然我需要通过更新的道具来获得新的slu。。 – user3178098

此问题与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] 
      }); 
      }); 
     } 
     } 
+0

为什么要等到更新后才使用setState? –

+0

我们也可以使用componentWillReceiveProps,它并不重要,无论如何都会将数据传递到状态 –

+0

使用componentDidUpdate钩子将导致无关渲染。这不是说这是世界上最糟糕的事情,而只是没有必要。 –