🖥️

【Nuxtjs】Mismatching childNodes vs. VNodes の対処方法

2021/03/19に公開

どういうエラー?

多分vueやNuxtで開発してる方は下記のエラーを一度くらい見たことあるじゃないでしょうか。

エラーメッセージを見て、DOMの書き方が誤ってるかどうか確認しても特に問題なかったし、ページの挙動は普通に動けるから、まあwarnだしとりあえず本番にリリースしてみようってリリースしたら今度は本番で違うエラーが出てきます。

なんじゃこりゃー 見たことないエラー出てきたぞーって大騒ぎして巻き戻しというオチw

一応ググったらいくつの記事が解決法を紹介されてますが、どれも解決できできませんでした。
最後にやっと正解にたどり着いたので共有します。

解決法

結論から言うとエラーメッセージに出てくるdom要素にv-ifで制御しているのであればv-showに変更してみてください

それでも解決できないなら多分この記事でも解決できなそうで申し訳ございません。

解説

実際のコードを簡略化して下記のようなコードです。

<a :href="hogehoge">
  <span
   v-if="isShow"
  >
  {{ text }}
  </span>
</a>

spanの表示はbooleanタイプのisShowで制御していて、isShowはAPIから取得しています。
極普通で特に問題ないコードに見えますが、今回のエラーが起きてしまいます。

これを下記にすればエラーを解消できます。

<a :href="hogehoge">
  <span
   v-show="isShow"
  >
  {{ text }}
  </span>
</a>

やることは簡単です。v-ifをv-showに変更するだけです。
ではなんでこれで問題を解決できるでしょう?

isShowはAPIから取得してるから、SSRの段階ではspanはまだありません。
そしてCSRの段階ではisShowはtrueの場合、spanタグはハイドレーションされて、そしたらdom要素の乖離が起きてしまい、エラーが起きるというわけです。

v-showにすることで、SSR段階で空のspan要素はレンダリングされて、CSRでハイドレーションしても問題が起きないということです。

最後に

以上、Mismatching childNodes vs. VNodesの原因と一つの解決法を詳細しました。

これで解決できないなら他の記事で紹介されてる方法で解決できるかもしれません。めげずにgoogleの海で解決法を探してみましょうw
最後に過去nuxt公式のgithubに上がったissueとスレを共有します。同じエラーにあった方の対処法や原因の説明なども書いてあります。ご参考になれば幸いです。

最後まで読んでいただきありがとうございました。

参考したリンク

Discussion