ヘルプ
サポート

外部DOM操作

サードパーティライブラリと連携する際に、DOMを自由に操作したり、状態を保持したり、コンポーネント境界を無視したりする必要がある場合があります。多くの優れたUIツールキットや再利用可能な要素はこのように動作します。

Preact(および同様にReact)では、これらのタイプのライブラリを扱うには、仮想DOMのレンダリング/差分アルゴリズムに、特定のコンポーネント(またはそれが表すDOM要素)内で実行された外部DOM操作を元に戻そうとしないように指示する必要があります。



手法

これは、コンポーネントにshouldComponentUpdate()メソッドを定義し、falseを返すようにするだけというシンプルな方法です。

class Block extends Component {
  shouldComponentUpdate() {
    return false;
  }
}

…または、簡略化すると

class Block extends Component {
  shouldComponentUpdate = () => false;
}

このライフサイクルフックを使用して、VDOMツリーの上位で変更が発生してもPreactがコンポーネントを再レンダリングしないようにすることで、コンポーネントは、コンポーネントがアンマウントされるまで静的として扱えるルートDOM要素への参照を持つようになります。他のコンポーネントと同様に、その参照は単にthis.baseと呼ばれ、render()から返されたルートJSX要素に対応します。


例を通して

コンポーネントの再レンダリングを「オフ」にする例を以下に示します。初期のDOM構造を生成するために、render()はコンポーネントの作成とマウントの一部として依然として呼び出されます。

class Example extends Component {
  shouldComponentUpdate() {
    // do not re-render via diff:
    return false;
  }

  componentWillReceiveProps(nextProps) {
    // you can do something with incoming props here if you need
  }

  componentDidMount() {
    // now mounted, can freely modify the DOM:
    let thing = document.createElement('maybe-a-custom-element');
    this.base.appendChild(thing);
  }

  componentWillUnmount() {
    // component is about to be removed from the DOM, perform any cleanup.
  }

  render() {
    return <div class="example" />;
  }
}

デモ

demo

Webpackbinでこのデモをご覧ください

実世界の例

あるいは、この手法が実際に使用されている様子をpreact-token-inputで確認できます。これは、コンポーネントをDOMへの足場として使用しますが、その後更新を無効にし、tags-inputに以降の処理を委譲します。より複雑な例としては、編集可能な<iframe>の再レンダリングを回避するためにこの手法を使用するpreact-richtextareaがあります。