React: Dispatch not firing on route change

2019-06-03 17:40发布

问题:

I have several routes that use the same controller:

<Route component={Search} path='/accommodation(/:state)(/:region)(/:area)' />

and when the route is changed I call the api function from within the component:

componentWillReceiveProps = (nextProps) => {
    if (this.props.params != nextProps.params) {
        loadSearch(nextProps.params);
    }
}

which is an action as follows:

export function loadSearch (params) {
    return (dispatch) => {
        return dispatch(
            loadDestination(params)
        ).then(() => {
            return dispatch(
                loadProperties(params)
            );
        });
    };
}

which loads:

export const DESTINATION_REQUEST = 'DESTINATION_REQUEST';
export const DESTINATION_SUCCESS = 'DESTINATION_SUCCESS';
export const DESTINATION_FAILURE = 'DESTINATION_FAILURE';

export function loadDestination (params) {
    const state = params.state ? `/${params.state}` : '';
    const region = params.region ? `/${params.region}` : '';
    const area = params.area ? `/${params.area}` : '';

    return (dispatch) => {
        return api('location', {url: `/accommodation${state}${region}${area}`}).then((response) => {
            const destination = formatDestinationData(response);

            dispatch({
                type: DESTINATION_SUCCESS,
                destination
            });
        });
    };
 }

export const PROPERTIES_REQUEST = 'PROPERTIES_REQUEST';
export const PROPERTIES_SUCCESS = 'PROPERTIES_SUCCESS';
export const PROPERTIES_FAILURE = 'PROPERTIES_FAILURE';

export function loadProperties (params, query, rows = 24) {
    return (dispatch, getState) => {

        const locationId = getState().destination.id || 99996;

        return api('search', {locationId, rows}).then((response) => {
            const properties = response.results.map(formatPropertiesData);

            dispatch({
                type: PROPERTIES_SUCCESS,
                properties
            });
        });
    };
 }

On initial page load this works and returns data from an api and renders the content. However on changing the route, the loadSearch function is fired but the dispatch (which returns the actual data) doesn't.

回答1:

Please change your code to this. You missed a dispatch.

Assumption : You are using redux-thunk, and the component has access to dispatch via props (connected). Since you mentioned that you are dispatching on page load, I think this is the case.

componentWillReceiveProps = (nextProps) => {
   const {dispatch} = this.props;
   if (this.props.params != nextProps.params) {
      nextProps.dispatch(loadSearch(nextProps.params));
   }
}