How to dispatch Redux action from stateless component when route is loaded?

I don’t know why you absolutly want a stateless component, while a stateful component with componentDidMount would do the job in a simple way.

Dispatching actions in mapDispatchToProps is very dangerous and may lead to dispatching not only on mount but whenever ownProps or store props changes. Side effects are not expected to be done in this method that should remains pure.

One easy way to keep your component stateless is to wrap it into an HOC (Higher-Order Component) that you could easily create:

MyStatelessComponent = withLifecycleDispatch(dispatch => ({
   componentDidMount: function() { dispatch({ type: myActionTypes.DATA_GET_REQUEST })};
}))(MyStatelessComponent)

Note that if you use Redux connect after this HOC, you can easily access dispatch from props directly as if you don’t use mapDispatchToProps, dispatch is injected.

You can then do something very simple like:

let MyStatelessComponent = ...

MyStatelessComponent = withLifecycle({
   componentDidMount: () => this.props.dispatch({ type: myActionTypes.DATA_GET_REQUEST });
})(MyStatelessComponent)

export default connect(state => ({
   date: state.myReducer.data
}))(MyStatelessComponent);

HOC definition:

import { createClass } from 'react';

const withLifeCycle = (spec) => (BaseComponent) => {
  return createClass({
    ...spec,
    render() {
      return BaseComponent();
    }
  })
}

Here is a simple implementation of what you could do:

const onMount = (onMountFn) => (Component) => React.createClass({
   componentDidMount() {
     onMountFn(this.props);
   },
   render() { 
      return <Component {...this.props} />
   }  
});

let Hello = (props) => (
   <div>Hello {props.name}</div>
)

Hello = onMount((mountProps) => {
   alert("mounting, and props are accessible: name=" + mountProps.name)
})(Hello)

If you use connect around Hello component, they you can inject dispatch as props and use it instead of an alert message.

JsFiddle

Leave a Comment

tech