【Vue】Vue3で「RangeError: Maximum call stack size exceeded」が出た

JavaScript

はじめに

タイトルの通り、Vue3を使って画面を開いたら「RangeError: Maximum call stack size exceeded」なんて、よくわからんエラーメッセージが出た話です。

まず、Vue3 + Quesarを使って、手始めにコンポーネントを作ってみようとQuasarの「q-table」をWrapしたコンポーネントを作りました。

しかし、いざ「npm run dev」を実行すると、Vueのロゴだけ出て表が表示されない・・・?開発者ツールを使ってコンソールを見るとタイトルのエラーが。。。

事象

Vueのロゴが神々しく輝いている。

本当は、ロゴの下に2列2行の表が表示される想定だったのですが、その描画までたどり着かず、コンソールにエラーメッセージが出力されている状態になっています。

開発環境

記事を作成した時点でのバージョンは以下の通りです。

  • Windows 10
  • Vue 3.2.45
  • Quasar 2.11.5

何らかの変更があったらバージョン上げるかもしれないので、最新はgithubに公開しているpackage.jsonで確認してください。(コードへのリンク

原因と解決策

原因

コンポーネントが自分のコンポーネントを呼び出すような作りになっていたためでした。作りが悪かった。。。

サンプルコード

コンポーネントのコード例です。とっても単純化してます。Quasar関係なく発生します。

ComponentA.vue
<template>
  <!-- ↓自コンポーネントを呼び出している -->
  <ComponentA />
  <div>コンポーネントA</div>
</template>

結果、「ComponentAをレンダリングし続け、stack sizeを超過する」というオチでした。

解決策

自コンポーネントを呼ばないようにしましょう。

が一番の解決策ですね。ただ、今回このケースにはまってしまった実例も書いておきます。

実例

実装してしまった背景

あまり理解をしていない状態、何とかなるだろ精神と以下の思いで作り出しました。

  • 表を使ってレイアウトしたかった
  • Quasarを使ってみたかった(Quasar超初心者)
  • QTableのサンプルは長かったので分離(=コンポーネント化)したかった

コンポーネント化自体はそこまで悩むことなく書き出せたのですが、名前が思いつかなかったんですよね。

そこで、別ファイルのソースコードにしておけば、違うものと認識するのではないか?と思い込んで「QTable.vue」という名前でコンポーネント名を決めてしまったんですねー。。

実装概要

App.vue

import QTable from ./component/QTable.vue
:(省略)
<header><img alt="Vue logo" …></header>  <!-- ロゴ表示 -->
<main><QTable /></main>
:(省略)

component/QTable.vue

:(script部分省略)
<template>
  <div class="q-pa-md">

    <!-- q-table = QTable。従って自コンポーネントの呼び出しとなり永久ループ -->
    <q-table
      title="サンプルテーブル"
      :rows="rows"
      :columns="columns"
      row-key="title"
    />
  </div>
</template>

結果、同じコンポーネントであると認識されてしまい、ひたすら自コンポーネントを描画しようとしてstack sizeを超過したというわけでした。

名前をQTable.vue → CustomQTable.vueに変更したところ、問題が解消され想定される画面表示ができるようになりました。

しかし結局名前がイケてない。

問題解消後の画面

無意味な表が表示されるようになりました。

サンプルテーブルがロゴの下に表示され、コンソールにもエラーが表示されることが無くなりました。Vue3 + Quasarで表の表示ができるようになった、という成功体験もゲット。

さいごに

あまり雑すぎる名前を付けるのは良くない、という学びを得ました。あとはどういうスコープになっているのか、というところも注目しないといけないな、と確認できました。(正直JavaScript系のスコープは理解があやふやなところが多いので)

注意点も一つ学べたので、また作りながら不具合と一緒に育っていきましょう。

ソースコード

この記事を書く起因となったソースコードは以下で公開しています。(GitHub)

コメント

タイトルとURLをコピーしました