Recompose: add mount option to lifecycle

Created on 19 Nov 2015  路  13Comments  路  Source: acdlite/recompose

lifecycle(
  setup: (component: ReactComponent) => void,
  mount: (component: ReactComponent) => void,
  teardown: (component: ReactComponent) => void,
  BaseComponent: ReactElementType
): ReactElementType

Add mount option to lifecycle that calls your function during componentDidMount. This will allow use for isomorphic/universal apps when you only want things ran on client and not on server.

Let me know what you think. I could probably get a PR in this week.

All 13 comments

+1 for this issue.
It looks inconsistent for now. I.e., we already dealing with DOM lifecycle hooks, in willUnmount - so why there is no other DOM hooks?

I've been thinking lately about removing lifecycle all together. The lifecycle methods are essentially useless without access to the component instance, in which case you should just use a class.

Does this make sense to anyone else? Is lifecycle really all that useful?

The lifecycle methods are essentially useless without access to the component instance

Well, not exactly. For example, you can start some timers when component is mounted - note, not in constructor, as it will cause problems with server-side rendering. Or, my own case, with which I came to this issue - a print page. It looks like this:

class PrintPage extends React.Component {
  render() {
    return (
      <Content {...this.props} />
    );
  }

  componentDidMount() {
    window.print();
  }
}

With didMount hook it could be just lifecycle(window.print, Content).

Sure, it's all a very edge cases. But they exist, and it's always nicely when there is a handy function which saves you from manually writing another boilerplate class =)

Have a question about:

What the idea to pass this as an argument to lifecycle methods, isn't it better to pass just props and some internal object to hold data across lifecycle events (_like window event handlers or some instance methods which depends on lifecycle_).

To get state access user can use lifecycle in combination with withState.

Does something like this will not be enough?

 class Lifecycle extends React.Component {
   internalObj_ = null

   componentWillMount() {
       this.internalObj_ = setup(props)
    }

    ...otherLifeCycleEventsIfNeeded

    componentWillUnmount() {
       teardown(this.props, this.internalObj_)
    }

    render() {
      return createElement(BaseComponent, {...this.props, ...this.internalObj_})
    }
  }

Without this, props could be changed at level above, so setup internals will have a ref on an old props version

My use case is just to load an SDK(braintree) during componentWillMount only on client side for later use. I don't need access to the wrapped component instance.

I've been using createSink or doOnReceiveProps when I need to deal with componentWillMount. Wouldn't that do for those use cases?

The downside is that it triggers on componentWillReceiveProps and sometimes you don't want that, e.g.: you may just want to trigger something once off. So perhaps something can be done there too (either once off components or a switch on those two).

What are your thoughts on this?

@dariocravero I use lifecycle for things like initial caches as well, where they aren't really depending on the props at all. Just a setState most of the time

Useful:

  • api calls
  • timeouts
  • intervals

voted for keeping doOnReceiveProps in another thread.
since it removed. at least provide a way to do something on Mount/NewProps since that helper was very handy really.

agree with @RafalFilipek

Here is simple way to intercept livecycle method calls:

import { compose, toClass } from 'recompose';

const enhance = compose(
  component => class extends toClass(component) {
    componentWillReceiveProps(nextProps) {
      if (nextProps.value !== this.props.value) {
        // Do something, value has changed.
      }
    }
  },
);

Simply extend the given component in the compose chain, and do whatever you need there.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

robbporto picture robbporto  路  3Comments

finom picture finom  路  3Comments

adrianmcli picture adrianmcli  路  3Comments

isubasti picture isubasti  路  3Comments

nemocurcic picture nemocurcic  路  3Comments