ReactとVue状態変化機構の違い


reactと比較して,Vueの最大の違いは状態の変化を認識できることである.
ステータスは、フロントエンドのレンダリングを制御する非常に重要な概念です.ただし、この状態の変化を認識するレンダリング方法はreactとVueとは異なります.この違いを理解する前にReactプレイヤーとしての私は自分の意図通りに行動しないVUEが非常に気分が悪いと思います.

アレイのステータスの変更を試みる


以下に簡単な例を示します.
ReactはusStateを使用して空の配列の状態を宣言します.次にこのボタンをクリックし、setStateのdestructuringを使用して'a'を追加して配列を変更します.
import { useState } from "react";

export default function App() {
  const [list, setList] = useState([]);

  const onClick = () => setList([...list, "a"]);

  return (
    <div className="App">
      <h1>List: {list.join(", ")}</h1>
      <button type="button" onClick={onClick}>
        add
      </button>
    </div>
  );
}

ステータスを新しいarrayに変更して再表示します.

では、Vueはどうですか.VUE状態のreactiveを使用して配列状態を宣言し、その後、同じ破壊を使用して'a'を追加する.
<script setup>
import { reactive } from 'vue'

const list = reactive([])
const onClick = () => {
  list = [...list , 'a']
}
</script>

<template>
  <h1> List: {{ list.join(', ')  }} </h1>
  <button @click='onClick'>
    add
  </button>
</template>

Vueは状態を新しいアレイに変更することに反応しない.

じゃあ今度は壊さない
reactでは、ボタンを押すと反応しません.
import { useState } from "react";

export default function App() {
  const [list, setList] = useState([]);

  const onClick = () => {
    list.push("a");
    setList(list);
  };

  return (
    <div className="App">
      <h1>List: {list.join(", ")}</h1>
      <button type="button" onClick={onClick}>
        add
      </button>
    </div>
  );
}


逆に、Vueでは再レンダリングが発生します.
<script setup>
import { reactive } from 'vue'

const list = reactive([])
const onClick = () => {
  list.push('a')
}
</script>

<template>
  <h1> List: {{ list.join(', ')  }} </h1>
  <button @click='onClick'>
    add
  </button>
</template>


ステータス管理メカニズムの違い


なぜこのような違いがあるのでしょうか.
これは,管理状態のメカニズムがリポジトリ(フレームワーク)と異なるためである.
Reactはstateを不変と見なします。すなわち、新しい状態と古い状態の値が異なる場合、再レンダリングされる.ここで、元のタイプ(string、numberなど)は値を比較し、オブジェクトは参照値(reference)を比較します.
したがって、分解によって新しい配列に置き換えると、新しい参照値がレンダリングのために渡され、pushによって古い参照値がそのまま使用されると、レンダリングは行われません.
しかし、VueはProxyを用いて状態比較を行う.
Proxyは、オブジェクトを囲み、そのオブジェクトに対して実行される操作、例えばPropertyの読み取りや書き込みを中間からブロックするオブジェクトです。です.すなわち、VUEのreactive関数はProxyオブジェクトを返し、setterがここで発生したことを追跡して再レンダリングする.
したがって、destructuringで新しい配列を宣言すると、既存のProxyが上書きされるため、レンダリングされません.既存のアレイをpushで変更すると、既存のProxyを検出して再レンダリングされます.
要するに,Reactは新しいbindを作成し,Vueは既存のbindを保持することを望んでいる.(個人的にはreactは関数式プログラミング(同じ値を入力すると同じ値を出力する)のように直感的だと言えるかもしれません.)

Vueでarrayを使用するには


では、Vueはdestructingを使用できませんか?map、filter、reduceなどの関数式プログラミング方法は使えませんか?
Proxyを理解すれば、ちょっとしたトリックができます.つまり、Proxyを上書きしないようにオブジェクトを囲みます.
<script setup>
import { reactive } from 'vue'

const list = reactive({a:[]})
const onClick = () => {
  list.a = [...list.a, 'a']
}
</script>

<template>
  <h1> List: {{ list.a.join(', ')  }} </h1>
  <button @click='onClick'>
    add
  </button>
</template>

これにより、Proxyリストの値を直接変更することなく、Proxy Propertyの変更を追跡でき、Proxyが消えないようにします.すなわち、Property aの変更を追跡することにより、再レンダリングが発生する.

実際,Vueはこれらの小細工を利用できる関数を提供した.これは次の文章で読んでみましょう.