React: ポータルとSSRで水分補給する際の予期しない警告

作成日 2018年04月15日  ·  24コメント  ·  ソース: facebook/react

機能をリクエストしバグを報告しますか?

バグ

現在の動作は何ですか?

次の(簡略化された)スニペットがあるとします。

class HoverMenu extends React.Component {
  render() {
    if (typeof document === 'undefined') return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

class Para extends React.Component {
  render() {
    return (
      <span>
        Some Text
        <HoverMenu />
      </span>
    )
  }
} 

div#rootが存在する有効なdivある場合、SSR後にハイドレートすると次のエラーが表示されます。

Warning: Expected server HTML to contain a matching <div> in <span>

HoverMenuの定義を次のように更新すると、警告は消えます。

class HoverMenu extends React.Component {
  componentDidMount() {
    this.setState({ isActive: true })
  }
  render() {
    const { isActive} = this.state
    if (!isActive) return null
    const root = document.getElementById('root')
    return ReactDOM.createPortal(<div>Hello World</div>, root)
  }
}

componentDidMount setStateによって二重レンダリングが発生するため、これは行いたくありません。

そのエラーが私に何を言っているのかよくわかりません。 どちらの場合も、 <div />はサーバー側にレンダリングされません。 HoverMenu DOM divはDOM span内にもレンダリングされないため、エラーは特に混乱を招きます。 ( HoverMenuがReact span内にネストされているため、これが発生しているのではないかと思います。)

期待される動作は何ですか?

エラーはスローされません。 または、少なくともエラーメッセージがより明確であること。

この問題の影響を受けるReactのバージョンとブラウザ/ OSはどれですか?

Chrome 65
React 16.2
(SSRからNext 5.1まで)

medium Bug good first issue

最も参考になるコメント

ポータルのハイドレイティングはサポートされていませんが(https://github.com/facebook/react/issues/13097)、メッセージ自体は意味がありません。 調査して修正する必要があります。

全てのコメント24件

同様の問題がありますが、setStateを介してクライアントで再レンダリングすることでも解決できます。
私の場合、ポータル内でモーダルをレンダリングしようとしています。 Modalコンポーネントは、サーバーでレンダリングされるとnull返し、クライアント上にポータルを作成します。 ただし、DOMは水和後に混乱します。

たとえば、メインコンポーネント内で次のように使用する場合:

<Modal>
This is a test
</Modal>

<div className="some-div-after-the-modal">
</div>

水分補給後にこれを得る代わりに:

<!-- Inside the portal container -->
<div class="modal-wrapper">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

私はこれを得る:

<!-- Inside the portal container -->
<div class="some-div-after-the-modal">
    <div class="modal-content">This is a test</div>
</div>

<!-- In the main component -->
<div class="some-div-after-the-modal">
</div>

そして警告は同じです( Expected server HTML to contain a matching <div> in <div> )。 カスタムSSRメソッドでReact16.3を使用しています。

これが意図した動作かどうかはわかりません。

ポータルのハイドレイティングはサポートされていませんが(https://github.com/facebook/react/issues/13097)、メッセージ自体は意味がありません。 調査して修正する必要があります。

@gaearon修正の目的は

  • []ポータルがhydrate()で使用されていることを検出し、不変条件によってより適切にエラーメッセージをスローします。
    例: invariant violation: Portal is not support on SSR. For more detail, please refer https://github.com/facebook/react/issues/13097
  • []テストを追加

    • []ポータルがhydrate()とともに使用されている場合、上記のエラーメッセージをスローする必要があります

正しい?
緊急でなければ喜んでいます。

SSR DocドラフトからWebサイトのリポジトリを計画しているので、ハイドレートメカニズムに精通している必要があります。
この調査は私の計画に役立つと思います。
https://github.com/facebook/react/pull/13379

「何も」レンダリングしない場合でも、ポータルがSSRでサポートされないのはなぜですか。

何もレンダリングするのが最善ではないようです。サーバーレンダリングの価値があるとは思わないポータルコンテンツの違いがわかりません。

サスペンス用のサーバーレンダラーの改良とともに、これに戻る可能性があります。

ポータルは、概念的にはクライアントのみのコンポーネントです。 一般的にサーバー上でレンダリングしたくないモーダルなどに使用されます。また、dom要素を取りますが、domがないためrenderToStringは取りません。 サーバー上でそれらを使用して実行する意味のあるものがどのようにあるのかわかりません-投げることから価値のあるものも何も見えません。

モーダルなどに使用されます

これは1つのユースケースですが、サイドバーなど、必ずしもクライアント専用ではないものもあります。

彼らはまた、dom要素を取ります

右—現在の設計では。 変わる可能性があります。 https://github.com/facebook/react/pull/8386#issuecomment -262375265

私はまた、投げることから価値のあるものを見ていません。

スローすることの価値は、ポータルが機能しないことを明示的に認めることです。 {domNode && ReactDOM.createPortal(stuff, domNode)}などで簡単に回避できます。 DOMノードを取得できるかどうかを判断するために、すでに何らかのチェックを行う必要があったため、この時点で、ポータルを発行しないことを選択するのに十分なデータが必要です。

これを私の「良い最初の問題」として修正したいと思います

+1

この問題に取り組むことはできますか?

承知しました。 できると思います。 それで、あなたはどこまで行ったのですか? 私も実際にそれを拾うことを考えています。

  • 2

こんにちは皆さん、問題のあるファイルを見つける方法がわかれば、助けてください。

この問題の部分的なプルリクエストはこちらです
https://github.com/facebook/react/pull/15473

まだこれをしている人はいますか? 私はそれを引き受けたいです。

これの状況はどうですか? どうすれば再現できますか?

これはまだ問題ですか?

私もこの問題についての返答を得ていません。

この問題の状況はまだ開いていると思います。

この問題に取り組むことはできますか?

こんにちは、この問題に取り組んでいる人はいますか? そうでなければ私はそれを取りたいと思います。

誰もそれに取り組んでいない場合、私はできます

これはまだ問題ですか? それを修正する試みがなされたようですが、根本的な問題は、一部の人々が実際にポータルをサーバー側のレンダリングで動作させたいということです。 その場合、この問題を解決できますか?

div要素の追加は正常に機能するはずです

`クラスParaはReact.Componentを拡張します{
render(){
戻る(

いくつかのテキスト
)

}
} `

このページは役に立ちましたか?
0 / 5 - 0 評価