初心者が知るべきReactとVue3の核心概念

## はじめに
この記事ではReactとVue3を比較しながら、Reactを迅速に習得するためのガイドを提供します。
• コンポーネント
• JSX
• インターポーラシオン
• データ通信
• レンダリング
• イベント
• ステート

## コンポーネント
「コンポーネント」という言葉を初めて聞いた時は抽象的でしたが、実際には特定の機能を持つUIの集まりです。例えば、ページを MyHeader、MyMain、MyFooter の3つのコンポーネントに分けることができます。例えば、他のページの下部に表示されるものは同じであると仮定すると（これは一般的です）、他のインターフェースでMyFooterコンポーネントを適用することができます。その後の変更も一度だけ変更する必要があります。


Vue：
```jsx
<MyHeader />
<MyMain />
<MyFooter />
```

React：
```jsx
<MyHeader />
<MyMain />
<MyFooter />
```


## **JSX**
    

コンポーネントの本質はJS関数です。MyHeaderコンポーネントを例として考えてみましょう：

Vue：

```js
// MyHeader.ts
export default {
  template: '<div>MyHeader</div>',
};

// SFC
// MyHeader.vue
<template>
  <divMyHeader</div>
</template>
```

React：

```tsx
// MyHeader.tsx
export default function MyHeader() {
  return <div>MyHeader</div>;
}
```

ReactではHTMLタグを返すことができますが、この文法はJSXと呼ばれています。これは以下に等しいです：

```ts
React.createElement('div', null, 'MyHeader');
```

VueでもJSX構文がサポートされています（プラグイン：@vitejs/plugin-vue-jsxを使用）。

```tsx
// MyHeader.tsx
import { defineComponent } from 'vue';

export const MyHeader = defineComponent({
  setup() {
    return () => <div>MyHeader</div>;
  }
})
```

 ## **インターポーレーション**
    

Vueでは、インターポーレーションは二重波括弧で表されますが、Reactでは単一の波括弧を使用します。

Vue：

```html
<h1>Hello, {{ msg }}.</h1>
```

React：

```jsx
<h1>Hello, {msg}.</h1>
```

5. ## **データ通信**
    

データ通信は値の伝達とコンポーネントの伝達に分けられていますが、どちらも外部からの伝達です。

### **値の伝達**
Vue：

```html
// Parent Component
<Coding who="me" />
<Coding who="you" />
<Coding who="them" />

// Coding.vue
<script setup>
defineProps(['who']);
</script>

<template>
  <div>Coding for {{ who }}.</div>
</template>
```

React：

```jsx
// Parent Component
<Coding who={'me'} />
<Coding who={'you'} />
<Coding who={'them'} />

// Coding.tsx
export default function Coding(props: { who: string }) {
  return <div>Coding for {props.who}.</div>;
}
```

### **5.2 コンポーネントの伝達**

スロットを通じてコンポーネントを伝達しますが、これはゲーム機のカードスロットやコンピュータの周辺インターフェースのようなものです。

Vue：

```html
<MyCard>This is my card.</MyCard>
<MyCard>
  <Coding who="boss" />
</MyCard>

// MyCard.tsx
<template>
  <div :style="{ border: '1px solid #000' }">
    <slot></slot>
  </div>
</template>
```

React：

```jsx
<MyCard>This is my card.</MyCard>
<MyCard>
  <Coding who={'boss'} />
</MyCard>

// MyCard.tsx
export default function MyCard({ children }: { children: React.ReactNode }) {
  return <div style={{ border: '1px solid000' }}>{children}</div>;
}
```


### ** リストのレンダリング**

Vue：

```jsx
const list = [
  { id: 1, name: '🍎', price: 6 },
  { id: 2, name: '🍌', price: 3 },
  { id: 3, name: '🍐', price: 5 },
];

<ul>
  <li v-for="item in list" :key="item.id">
    {{ item.name }}-{{ item.price }}
  </li>
</ul>
```

React：

```jsx
<ul>
  {list.map((item) => (
    <li key={item.id}>
      {item.name}-{item.price}
    </li>
  ))}
</ul>
```

### **6.2 条件付きレンダリング**

Vue：

```jsx
const visible = false;

<div>
<p v-if="visible"> show </p>
<p v-else> hidden </p>
</div>
```

React：

```jsx
const visible = false;
<div>
{visible ? <p>show</p> : <p> hidden</p> }
</div>
```

 ## **イベント**
    

ウェブページでは多くのインタラクション機能を実現できますが、さまざまなイベントを活用します：クリックイベント、マウス移動イベント、キーボードクリックイベントなど…

Vue：

```jsx
<form
  @submit="
    (e) => {
      e.preventDefault();
      console.log('submit');
    }
  ">

  <input @change="(e) => console.log('something change：', e.target.value)" />
  <button @click="() => console.log('clicked')"> sumbit </button>
</form>
```

React：

```jsx
<form
  onSubmit={(e) => {
    e.preventDefault();
        console.log('submit');
  }}>

  <input onChange={(e) => console.log('something change：', e.target.value)} />
  <button onClick={() => console.log('clicked')}>sumbit  </button>
</form>
```

 ## **ステート**
    
Vueでは、ref（リアクティブ参照）、reactive()（リアクティブオブジェクト）というメソッドを使用してステートを管理しますが、ReactではuseStateメソッドを使用します。

Vue：

```jsx
import { ref } from 'vue';

const count = ref(0);

<p> {{ count }}</p>
<button @click="() => count++"+1</button>
```

React：

```jsx
import { useState } from 'react';

const [count, setCount] = useState(0);

<p>{count}</p>
 <button onClick={() => setCount(count + 1)}>+1</button>
```

ユーザーがボタンをクリックすると、setCountがトリガーされます。
ステートcountを更新します。
{count}は新しいステートを読み取ります。