-->

React router + redux navigating back doesn't c

2019-05-06 10:34发布

问题:

Currently I pre-load data from api in container component's lifecycle method componentWillMount:

componentWillMount() {
  const { dept, course } = this.props.routeParams;
  this.props.fetchTimetable(dept, course);
}

It is called when user navigates to route /:dept/:course, and it works fine, until you navigate from let's say: /mif/31 to /mif/33 and then press back button. The component is not actually reinitialized, so the lifecycle method is not called, and the data isn't reloaded.

Is there some sort of way to reload data in this case? Should I maybe use another method of preloading data? I see react router emits LOCATION_CHANGE event on any location change, including navigating back, so maybe I can somehow use that?

If it matters, here's is how I implement data loading:

import { getTimetable } from '../api/timetable';

export const REQUEST_TIMETABLE = 'REQUEST_TIMETABLE';
export const RECEIVE_TIMETABLE = 'RECEIVE_TIMETABLE';

const requestTimetable = () => ({ type: REQUEST_TIMETABLE, loading: true });
const receiveTimetable = (timetable) => ({ type: RECEIVE_TIMETABLE, loading: false, timetable });

export function fetchTimetable(departmentId, courseId) {
  return dispatch => {
    dispatch(requestTimetable());
    getTimetable(departmentId, courseId)
      .then(timetable => dispatch(receiveTimetable(timetable)))
      .catch(console.log);
  };
}

回答1:

You need to use componentWillReceiveProps to check if new props (nextProps) are same as existing props (this.props). Here's relevant code in Redux example: https://github.com/reactjs/redux/blob/e5e608eb87f84d4c6ec22b3b4e59338d234904d5/examples/async/src/containers/App.js#L13-L18

componentWillReceiveProps(nextProps) {
  if (nextProps.dept !== this.props.dept || nextProps.course !== this.props.course) {
    dispatch(fetchTimetable(nextProps.dept, nextProps.course))
  }
}


回答2:

I might be wrong here, but I believe the function you are looking for is not componentWillMount but componentWillReceiveProps,

assuming you are passing down variables (like :courseId) from redux router to your component, using setState in componentWillReceiveProps should repaint your component.

Otherwise, you can subscribe to changes in your store: http://redux.js.org/docs/api/Store.html

Disclaimer: I probably know less about redux then you.