Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Intercept component unmounting (Functional and Class Components)

I need to always intercept when React unmounts a Component, no matter if that is a Functional or Class based component.

Here is my case:

function observe(component) {
  const p = component.type.prototype;
  const delegate = p.componentWillUnmount || function noop() {};

  if(!delegate.__decorated) {
    p.componentWillUnmount = function() {
      console.log('I am going to be unmounted');

      return delegate.apply(this, arguments);
    }

    p.componentWillUnmount.__decorated = true;
  }

  return component;
}

class Comp extends React.Component {

  render() {

    return (<h1>Hello World</h1>);
  }
}

class App extends React.Component {

  render() {
    const active = this.state && this.state.active;
    const toggle = () => this.setState({
      active: !active,
    });

    return (
      <div>
        <button onClick={toggle}>Toggle</button>
        <hr />
        {active && observe(<Comp />)}
      </div>
    );
  }
}

Now, as you can easily see, I am able to hook on every time <Comp /> gets unmounted. That is just what I need.

Things will dramatically change when that <Comp /> is a functional component:

function observe(component) {
  const p = component.type.prototype;
  const delegate = p.componentWillUnmount || function noop() {};

  if(!delegate.__decorated) {
    p.componentWillUnmount = function() {
      console.log('I am going to be unmounted');

      return delegate.apply(this, arguments);
    }

    p.componentWillUnmount.__decorated = true;
  }

  return component;
}



function Comp() {

  return (<h1>Hello World</h1>);
}


class App extends React.Component {

  render() {
    const active = this.state && this.state.active;
    const toggle = () => this.setState({
      active: !active,
    });

    return (
      <div>
        <button onClick={toggle}>Toggle</button>
        <hr />
        {active && observe(<Comp />)}
      </div>
    );
  }
}

So, my question is:

How can I hook on functional components?

I can change approach (or use React internal Apis), I just need to always intercept changes on a component passed as arguments for observe.

like image 204
Hitmands Avatar asked Oct 28 '17 10:10

Hitmands


1 Answers

You can't. Functional components don't have lifecycles (yet).

Instead of messing with the functional component directly, why don't you just wrap the functional component in a class with a HOC. You could use recompose toClass for this.

function observe(component) => {
  const classComponent = toClass(component):
  const p = classComponent.type.prototype;
  const delegate = p.componentWillUnmount || function noop() {};

  if(!delegate.__decorated) {
    p.componentWillUnmount = function() {
      console.log('I am going to be unmounted');

      return delegate.apply(this, arguments);
    }

    p.componentWillUnmount.__decorated = true;
  }

  return classComponent;
}

Or just copy the code from here.

like image 122
Martin Dawson Avatar answered Nov 15 '22 16:11

Martin Dawson