4

下面根据链接反应的代码说:

不幸的是,这可能会导致服务器渲染的内存泄漏(永远不会调用 componentWillUnmount)

// Before
class ExampleComponent extends React.Component {
  componentWillMount() {
    this.setState({
      subscribedValue: this.props.dataSource.value,
    });

    // This is not safe; it can leak!
    this.props.dataSource.subscribe(
      this.handleSubscriptionChange
    );
  }

  componentWillUnmount() {
    this.props.dataSource.unsubscribe(
      this.handleSubscriptionChange
    );
  }

  handleSubscriptionChange = dataSource => {
    this.setState({
      subscribedValue: dataSource.value,
    });
  };
}

我不明白这怎么可能是服务器端的内存泄漏。例如,假设我们有这个在服务器端呈现的代码,并且 ExampleComponent 包含内存泄漏。

import React from 'react';
import ReactDomServer from 'react-dom/server';
import App from './components/index'

const serverRender =  () =>{
    return ReactDomServer.renderToString(<ExampleComponent />);
};

export default serverRender;

当这返回到客户端时,渲染的组件不会附加到任何地方并准备好被 GB 收集。那么为什么会出现内存泄漏呢?

4

2 回答 2

2

文档中暗示了答案:

人们经常假设componentWillMount并且componentWillUnmount总是配对,但这并不能保证

有一个明显的原因是componentWillMount当组件即将安装时运行,所以如果安装被中断,那么组件将永远不会安装,因此永远不会卸载。然而,在文档的上一节中也有暗示的原因,它显示了代码:

componentWillMount() {

    this.setState({
      subscribedValue: this.props.dataSource.value,
    });

    // This is not safe; it can leak!
    this.props.dataSource.subscribe(
      this.handleSubscriptionChange
    );

} 

并说

上面的代码对于服务器渲染(不会使用外部数据)和即将到来的异步渲染模式(可能会多次启动请求)都是有问题的。

从这一点可以假设它componentWillMount在 SSR 期间运行,并且在客户端补水时也运行,这意味着有一个额外的不必要的请求被提出,导致服务器上潜在的内存泄漏。

但是,如果您使用componentDidMount,则可以保证:

  1. 仅在客户端运行
  2. 确保componentWillUnmount之后总是运行
于 2019-03-22T07:40:11.367 回答
0

this.props.dataSource是外部的东西,可以比调用的组件寿命更长subscribehandleSubscriptionChange将被引用this.props.dataSource。组件本身也可能被thisinside引用handleSubscriptionChange。所以GB根本不会清理ExampleComponent

由于componentWillMount已被弃用,您可能不必担心这些细节,只需使用componentDidMaount.

于 2019-03-22T07:30:23.413 回答