2017-08-04 134 views
4

我遇到了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; 

回答

1

您的<Lesson />組件僅在componentDidMount生命週期掛鉤期間設置課程。如果您正在上課並且您更改了slu,,它不會導致組件重新裝入。您可以使用componentWillReceiveProps生命週期掛鉤來完成您的工作。

componentWillReceiveProps(nextProps) { 
    api.getLesson(nextProps.match.params.lesson) 
     .then((lesson) => { 
      this.setState({ 
      lesson: lesson[0] 
     }); 
    }); 
} 
+0

這是我需要的正確方向的一點!謝謝。雖然我需要通過更新的道具來獲得新的slu。。 – user3178098

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] 
      }); 
      }); 
     } 
     } 
+0

爲什麼要等到更新後才使用setState? –

+0

我們也可以使用componentWillReceiveProps,它並不重要,無論如何都會將數據傳遞到狀態 –

+0

使用componentDidUpdate鉤子將導致無關渲染。這不是說這是世界上最糟糕的事情,而只是沒有必要。 –

相關問題