componentDidMount not called
javascript, react-router, reactjs
Solution
I think calling the getCourse in the componentWillReceiveProps and not in ComponentDidMount will solve your issue.
componentWillReceiveProps(nextProps) {
var nextId = nextProps.params.id;
if (nextId !== this.props.params.id) {
CourseApi.getCourse(nextId).then(courseData => {
this.setState({ course: courseData });
}).catch(error => {
throw(error);
});
}
}
Problem
I have a component that does not appear to be firing the `componentDidMount` event. The component is a parent that is accessed using react-router Link via another component. here is my list component and the child components: CoursesPage ``` import React from 'react'; import CourseList from './CourseList'; import CourseApi from '../../api/courseApi'; import {browserHistory} from 'react-router'; class CoursesPage extends React.Component { constructor(props, context) { super(props, context); this.state = { courses: [] }; this.redirectToAddCoursePage = this.redirectToAddCoursePage.bind(this); } componentDidMount(){ CourseApi.getAllCourses().then(coursesData => { this.setState({ courses: coursesData }); }).catch(error => { throw(error); }); } redirectToAddCoursePage() { browserHistory.push('/course'); } render() { const courses = this.state.courses; return ( <div> <div className="page-header"> <h3>Courses</h3> </div> <input type="submit" value="New Course" className="btn btn-default btn-toolbar pull-right" onClick={this.redirectToAddCoursePage} /> <div className="panel panel-default "> <div className="panel-heading"> <span> </span> </div> <CourseList courses={courses} /> </div> </div> ); } } export default CoursesPage; ``` CourseListRow ``` import React from 'react'; import PropTypes from 'prop-types'; import CourseListRow from './CourseListRow'; const CourseList = ({courses}) => { return ( <table className="table table-hover"> <thead> <tr> <th>Id</th> <th>Title</th> <th>Author</th> <th>Category</th> <th>Length</th> </tr> </thead> <tbody> { courses.map(course => <CourseListRow key={course.CourseId} course={course} /> )} </tbody> </table> ); }; CourseList.propTypes = { courses: PropTypes.array.isRequired }; export default CourseList; ``` CourseListRow ``` import React from 'react'; import PropTypes from 'prop-types'; import {Link} from 'react-router'; const CourseListRow = ({course}) => { return ( <tr> <td><Link to={'/course/' + course.CourseId}>{course.CourseId}</Link></td> <td>{course.Title}</td> <td>{course.Author.FirstName + ' ' + course.Author.LastName}</td> </tr> ); }; CourseListRow.propTypes = { course: PropTypes.object.isRequired }; export default CourseListRow; ``` My routes ``` import React from 'react'; import { Route, IndexRoute } from 'react-router'; import App from './components/App'; import CoursesPage from './components/course/CoursesPage'; import ManageCoursePage from './components/course/ManageCoursePage'; export default ( <Route path="/" components={App}> <IndexRoute component={HomePage} /> <Route path="courses" component={CoursesPage} /> <Route path="course" component={ManageCoursePage} /> <Route path="course/:id" component={ManageCoursePage} /> </Route> ); ``` All of the above components work fine. However, when I click on the Link for a course in the CourseListRow component to route to the component below, the state for the course object is always empty. I put a debugger statement in the componentDidMount event and it never hits it, so this components CourseForm child component (not shown) never gets the course: ``` import React from 'react'; import PropTypes from 'prop-types'; import CourseForm from './CourseForm'; import {authorSelectData} from '../../selectors/selectors'; import CourseApi from '../../api/courseApi'; import AuthorApi from '../../api/authorApi'; export class ManageCoursePage extends React.Component { constructor(props, context) { super(props, context); this.state = { course: {}, authors: [], }; } componentDidMount() { let id = this.props.params.id; if (id) { CourseApi.getCourse(id).then(courseData => { this.setState({ course: courseData }); }).catch(error => { throw(error); }); } AuthorApi.getAllAuthors().then(authorsData => { this.setState({ authors: authorSelectData(authorsData) }); }).catch(error => { throw(error); }); } render() { return ( <CourseForm course={this.state.course} allAuthors={this.state.authors} /> ); } } ManageCoursePage.contextTypes = { router: PropTypes.object }; export default ManageCoursePage; ``` For the life of me, I cannot figure why componentDidMount is not firing and populating the course state object. Any help is appreciated Follow up: I changed my render method of my parent (ManageCoursePage) component to the following, commenting out the CourseForm child compnonent: ``` render() { return ( <h2>Hi {this.state.course.CourseId}</h2> /*<CourseForm course={this.state.course} authors={this.state.authors} onChange={this.updateCourseState} onSave={this.saveCourse} onDelete={this.deleteCourse} onCancel={this.cancelChange} errors={this.state.errors} saving={this.state.saving} deleting={this.state.deleting} />*/ ); } ``` This worked, I got "Hi 11". It appears for whatever reason my child component is not receiving the props from my parent. Could this be something to do with react router, that I am missing something? This has me really perplexed