简体   繁体   中英

How to execute a method in component after a async dispatch completes(thunk or action creator)?

I am using redux with redux-thunk for async actions.

in my component I have the following code

class Counter extends Component {

    componentDidMount() {

    }

    notify() {
        ////some logic
    }

    //
    // other code
    //
    render() {
        // code
    }
}

const mapStateToProps = (state) => {
    return {
        items: state.items,
        hasError: state.itemsHaveError,
        isLoading: state.itemsAreLoading
    };
};

const mapDispatchToProps = (dispatch) => {
    return {
        fetchData: (url) => dispatch(itemsFetchData(url))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(ItemList);

and my code for the method is

function itemsFetchData(url) {
    return (dispatch) => {
        dispatch(itemsAreLoading(true));

        axios.get(url)
            .then((response) => {
                if (response.status !== 200) {
                    throw Error(response.statusText);
                }

                dispatch(itemsAreLoading(false));

                return response;
            })
            .then((response) => dispatch(itemsFetchDataSuccess(response.data)))
            .catch(() => dispatch(itemsHaveError(true)));
    };
}

My requirement is that in the componenentDidMount method I should be able to do like this

componentDidMount() {
   this.props.fetchData('https://.....').then(res => {
       this.notify();
       /// or do something else;
   })
}

Can Anybody help or you need any other inputs or a working sandbox.. please reply.

Your thunk function itemsFetchData returns function, that is ok.

But that returned function does not return anything, you are not propagating your return response; . You should return the promise that is axios.get(url) returning:

function itemsFetchData(url) {
    return (dispatch) => {
        dispatch(itemsAreLoading(true));

        // you need to return promise from thunk
        return axios.get(url)
            .then((response) => {
                if (response.status !== 200) {
                    throw Error(response.statusText);
                }

                dispatch(itemsAreLoading(false));

                return response;
            })
            .then((response) => dispatch(itemsFetchDataSuccess(response.data)))
            .catch(() => dispatch(itemsHaveError(true)));
    };
}

IMO better way than listening to than function on dispatched action creator, you should set something in your redux (eg dataLoadedSuccessfully to true in reducer handler for the action creator itemsFetchDataSuccess ) and check for change of it in componentDidUpdate , eg:

componentDidUpdate(prevProps) {
   if (this.props.dataLoadedSuccessfully && this.props.dataLoadedSuccessfully !== prevProps.dataLoadedSuccessfully) {
       this.notify();       
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM