拦截 React 组件卸载(函数式和类组件)

13

我需要在React卸载组件时始终进行拦截,无论是基于函数还是基于的组件。

这是我的情况:

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>
    );
  }
}

现在,正如你可以轻松地看到的一样,每当<Comp />被卸载时,我都能够挂钩。 这正是我所需要的

<Comp />为函数组件时,情况将发生重大变化:

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>
    );
  }
}

因此,我的问题是:

我如何在函数式组件中做钩子?

我可以改变方法(或使用React内部API),我只需要始终拦截作为参数传递给observe的组件的更改。


如果您需要生命周期方法,您应该将一个函数式组件转换为类组件。参考 - Gabriel Bleu
请查看 https://github.com/rkendall/visible-react,不确定该代码是否适用于函数组件。事实上,目前这是不可行的。 - hazardous
你可以查看这个库react-functional-lifecycle,它基本上将生命周期方法添加到基于函数的类中。 - Sheshnath
1个回答

14

你不能这样做。函数组件还没有生命周期(至少目前还没有)。

相反,为什么不直接将函数组件包装在一个带有高阶组件的类中呢?你可以使用Recompose的toClass来实现这一点。

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;
}

或者只需从这里复制代码。


^ this. 高阶组件(HOC)是这里的最佳选择。 - Mike S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接