🎨

【徹底比較】Vue.js と React でレンダリングされる値、されない値

2024/02/26に公開
3

フロントエンドの開発・デバッグ中にコンポーネント内の変数や props の値を確認したい時、console.log() で出力するよりも画面上にレンダリングしてしまう方が分かりやすい場合もあります。
コンソール出力は値の変化をリアルタイムで確認するには不向きです。一方、画面上にレンダリングすると、値の変化を直感的に把握できます。特に、複雑な状態管理をしている場合や、アニメーションなど時間経過に伴って値が変化する場合などに有効です。

筆者は Vue.js の経験が長いのですが、React を書いている時に「おや、この値はレンダリングされないのか」と感じたことがありました。興味が出たので色々な値を両者でレンダリングしてみることにしました。

多様な種類の変数に対して、Vue.js のテンプレートでは {{ value }} で、JSX では {value} でレンダリングした結果が以下のとおりです。ついでに Vue + JSX のパターンも試しています。

Vue Vue + JSX React
true true
false false
-1 -1 -1 -1
0 0 0 0
1 1 1 1
NaN NaN NaN NaN *1
Infinity Infinity Infinity Infinity
BigInt: -1n -1 -1
BigInt: 0n 0 0
BigInt: 1n 1 1
String: ''
String: 'a' a a a
String: '0' 0 0 0
null
undefined
Symbol(foo) Symbol(foo) Symbol(foo)
Array: [] []
Array: [0, 1, 2] [ 0, 1, 2 ] 012 012
Object: {} {} *2 (エラー *4
Object: { foo: 'bar' } { foo: bar } *2 (エラー *5
Object: new Date() toString() の結果 *3 *2 (エラー *6
Set: [0, 1, 2] { Set(3): [ 0, 1, 2 ] } *2 012
Map: { foo: 'bar' } { Map(1): { foo =>: bar } } *2 foobar *7
Function: () => {} () => {} () => {} *8
注釈
  • *1. 画面に表示されるがコンソールにエラーが出る。
    Warning: Received NaN for the `children` attribute. If this is expected, cast the value to a string.
  • *2. 画面には表示されずコンソールにワーニングが出る。
    [Vue warn]: Invalid VNode type: undefined (undefined)
  • *3. Chrome だと以下の形式(実行環境によって異なる可能性あり)。
    Mon Jan 01 2024 00:00:00 GMT+0900 (GMT+09:00)
  • *4. ランタイムエラー。
    Uncaught Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.
  • *5. ランタイムエラー。
    Uncaught Error: Objects are not valid as a React child (found: object with keys {foo}). If you meant to render a collection of children, use an array instead.
  • *6. ランタイムエラー。
    Uncaught Error: Objects are not valid as a React child (found: [object Date]). If you meant to render a collection of children, use an array instead.
  • *7. 画面に表示されるがコンソールにエラーが出る。
    Warning: Using Maps as children is not supported. Use an array of keyed ReactElements instead.
  • *8. 画面には表示されずコンソールにエラーが出る。
    Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

いくつかの項目で違いが見られますね。まず、JSX 内で真偽値は表示されないのが特徴的です。これは条件付きの箇所を value && <Foo /> のように簡潔に記述できるようにするためでしょうか[1]。そして、Vue.js では BigInt がそのまま数値として表示できることが分かりました。
さらに、プリミティブ値以外では三者三様となり、同じ Vue.js でもテンプレートと JSX で表示が異なっている点も興味深いです。

このように、Vue.js と React で値をレンダリングする際には、それぞれ異なる挙動があることが分かりました。
繰り返しになりますが、オブジェクトや配列を直接レンダリングできるからといって {{ someObject }} のようなコードを書くことを推奨しているわけではありません。デバッグのための一時的な表示のみにとどめ、コミットするコードではきちんとループ等で処理するようにしましょう。
この記事が誰かのお役に立てば幸いです。

脚注
  1. もし真偽値を表示してしまうと、毎回 value ? <Foo /> : null のように記述しないといけなくなる。Vue テンプレートは v-if で切り替えるので関係ない。 ↩︎

Discussion