LoginSignup
8
4

More than 5 years have passed since last update.

React で異なる Renderer を混ぜる際にメモリリークを防ぐ

Last updated at Posted at 2018-04-12

https://github.com/michalochman/react-pixi-fiber を使っていてちょっとハマったのでメモ

react-pixi-fiber のような、ReactDOM以外の異なる reconciler を要求される場合、別マウントで render し直す必要がある。

最初こんな感じのコードを書いた

// import は省略

class PIXIApp extends React.Component {
  componentWillUnmount() {
    // 終了処理
  }
  render() {
    return (
      <Stage
        width={300}
        height={300}
        options={{ backgroundColor: 0x10bb99 }}
       >
         <Text text={Date.now().toString()} x={200} y={200} />
       </Stage>
    )
  }
}

class PIXIAppContainer extends React.PureComponent {
  containerRef = React.createRef()
  componentDidMount() {
    ReactDOM.render(<PIXIApp />, this.containerRef.current)
  }
  render() {
    return <div ref={this.containerRef} />
  }
}

(createRef は v16.3.0 からの機能)
PIXIAppContainer から PIXIApp をマウントする。
よく考えればわかるが、これだと PIXIAppContainer はツリー外なので、 PIXIAppContainer の unmount で PIXIApp の unmount が行われず、マウントし直した回数だけインスタンス分のメモリがリークする。

解決策

ちゃんと自分の componentWillUnmount で ReactDOM.unmountComponentAtNode を呼びましょう

class PIXIAppContainer extends React.PureComponent {
  containerRef = React.createRef()
  componentDidMount() {
    ReactDOM.render(<PIXIApp />, this.containerRef.current)
  }

  componentWillUnmount() {
    ReactDOM.unmountComponentAtNode(this.containerRef.current)
  }

  render() {
    return <div ref={this.containerRef} />
  }
}

考えてみたら当然なんだけど、書いてる最中は気づかなくてハマった。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4