React.js・Next.jsの書籍を拝読してのアウトプット

### 概要
[React.js&Next.js超入門 第2版](https://www.shuwasystem.co.jp/book/9784798063980.html)を拝読し、React.js・Next.jsの学習を行ったためその内容をアウトプットする。

## 基本的な使い方
### エレメントの生成
```js
// ここで生成しているのはDOMではなく仮想DOM
  let element = React.createElement(
    タグ名, 属性, 中に組み込まれる記述
  )
```
属性の箇所は何もなければ`{}`を記載する。

### レンダリング
```js
ReactDOM.render(仮想DOMのエレメント, 本来のDOM)
```

### JSX
1つのエレメントを生成する。
Javascriptのコードを古いJSにコンパイラする。
以下記述で使用可能である。

```js
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// ここに記載
</script>
```

JSXでは、JavaScriptの記述を`{}`で使用する。

```jsx
// 変数
{変数}
// 条件分岐
{真偽値 && JSXの記述}
// 三項演算子
{条件 ? trueの場合 : falseの場合;
```
※条件分岐だと、真偽値が満たされる場合に右側のJSXの記述が表示される。

#### 配列
#### 使用例

```jsx
let data = [
    <li className="list-group-item">One</li>,
    <li className="list-group-item">Two</li>,
    <li className="list-group-item">Three</li>
]

<ul className="list-group mt-4">
    {data}
</ul>
```
`<ul>タグ`に`liタグ`が連なる。

#### map
#### 使用例
配列を格納した`data`という変数にmapを使用している。
```jsx
let data = [
    {name:'Yamada', mail:'yamada@test', age:45},
    {name:'Hanako', mail:'hanako@test', age:37},
]

{data.map((value) =>(
    <tr>
      <td>{value.name}</td>
      <td>{value.mail}</td>
      <td>{value.age}</td>
    </tr>
))}
```

即時実行関数も使用可能である。

```jsx
{(()=> JSX )}
```

## コンポーネント
### 概要
表示内容・データ・処理を1つのオブジェクトにまとめたもので、画面に表示される部品である。
コンポーネント名の1文字目は必ず大文字で記載する必要がある。

### 関数コンポーネント
#### 定義

```jsx
function コンポーネント名(){
  return /* JSXの記述 */
}
```

#### 呼び出し
```jsx
<コンポーネント名/>
```

#### 関数コンポーネントの引数
関数コンポーネントの引数ではタグの属性を使用できる

```jsx
// 関数定義
function Com(att){
  // 使用例
  return <p className={att.fontSize}>Hello {att.name}</p>
}

// 呼び出し側
<Com name="Taro" fontSize="h2" />
```

### クラスコンポーネント
#### クラス基本的な記載は以下

```jsx
class クラス名 {
  constructor(props){
    super(props)
    // 初期化処理
  }
  // プロパティやメソッドを記載する
  メソッド名 (){
  // 処理
  }
}
```
#### constructorメソッド
オブジェクトの初期化を行う。
引数は1つだけ用意されており、属性の値をオブジェクトにまとめたものが渡される。
`super()`の記述では、後述するextendsで継承しているクラスのconstructorを呼び出すための記述である。

#### コンポーネントのクラス
コンポーネントのクラスでは、extendsを使用して定義する。

```jsx
class クラス名 extends 継承するクラス {}
```

自分でコンポーネントを定義する場合は`React.Componnt`というコンポーネントの機能を取り揃えたクラスを継承して作成する。

#### renderメソッド
コンポーネントクラスには必ずrenderメソッドが必要である。
```jsx
render(){
  returun // JSXの記述
}
```

## Creat React App
読み込まれる順番は以下である。
1. index.htmlが読み込まれる。
2. index.htmlを読み込む際にindex.jsが読み込まれて実行される
3. index.jsの中でAppコンポーネントが読み込まれ表示される。 

以下で各ファイルの説明を行う。

```index.html 
<noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
```
`noscript`はJavaScriptが動作しない環境の時に表示される。
Reactでは、Reactを組み込む用のタグが1個あるというのが一般的な実装方法である。

```index.js
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
```

```js
import reportWebVitals from './reportWebVitals';
```
上記でアプリのパフォーマンスなどを分析する。

```js
<React.StrictMode></React.StrictMode>
```

上記で厳格モードを設定可能である。

```js
<App />
```
上記で`App`コンポーネントを読み込んでいる。

## ステート
### 概要
- Componentを継承したクラスコンポーネントで利用する値の保管庫。
- コンポーネントの状態を扱い、操作することができる。
- ステートを変更すれば自動的に表示が更新される。

ステートはクラスコンポーネントのみで使用できていたが、フックを使用することで関数コンポーネントで使用できるようになった。

#### プロパティ
クラスの値を保管しておくのに使用する。
コンポーネントに限らずクラス全般で利用される。
#### 属性
コンポーネントとの属性をまとめて保管するためのもので基本的にreadのみ。
#### ステートの初期化

```jsx
class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      msg:'Hello Component.',
    }
  }
  this.state.msg
}
```
#### ステートの更新
```jsx
this.setState( { 値 } )
```

子エレメントの受け渡しを下記で実施できる。

```jsx
class App extends Component {
  input = ''

  constructor(props){
    super(props)
  }

  render(){
    return 
        <Message title="Children!">
          コンテンツ
        </Message>
  }
}
class Message extends Component {
 render(){
  //受け取り
this.props.children
}
}
```

入力した値をチェックする。
```jsx
<input type="text" className="form-control" 
required pattern="[A-Za-z _,.]+" />
```
`required `・・・必須
`pattern`・・・正規表現

## コンテキスト
### 概要
コンポーネント全体で共通して使用可能である。

### 使用方法
以下をクラスの外で定義する。
```jsx
const 変数 = React.createContext(値)
```

以下で使用可能である。
```jsx
// 「static contextType」という記述は固定で記載する。クラス内にこの記述をするとコンテキストがそのクラスで使用可能になる。
static contextType = コンテキスト

// 以下にまとめられる。
this.context

// 更新する。
this.context.message = "test"
```

#### 一部のコンポーネントでコンテキストの値を変更する

```jsx
const a = React.createContext(変更前の値)

<コンポ―ネント/>
<a.Provider value={変更後の値}>
  <コンポ―ネント/>
</a.Provider>
```
`Provider`内にあるコンポーネントのみコンテキストの値が変更されている。

## Hooks
Reactでは、ステートを関数コンポーネントで使用することができなかったが、Hooksが出てきたことによって使用可能になった。
クラスコンポーネントでは、thisやbindなどの記述が複雑になりがちだったため、Hooksを使用した関数コンポーネントを使用することがおすすめ。
ステートを含むコンポーネントの処理を再利用することができる。
### Hooksの種類
Hooksにはいくつかの種類がある。
#### ステートフック
`useState`を使用してステートフックを作成できる。

```js
import React, { useState } from 'react'
const [変数A, 変数B] = useState(初期値)
```
変数A・・・ステートの値、現在のステートの値が得られる。
変数B・・・ステートの値を変更する関数。この変数に引数をつけて呼び出すことでステートの値を変更する。
※useStateを使用する場合（ステートの種類によって異なる）

簡易的な仕様イメージは以下である。
```jsx
const [count, setCount] = useState(0)
const clickFunc = () => {
  setCount(count + 1)
}
<button onClick={clickFunc}>{count}</button>
```
buttonタグをクリックすると`clickFunc`関数が実行され、ステートの値を変更する`setCount`関数が呼び出される。
`setCount`関数では、`count`ステートに1を足すようにしている。
よって`button`タグをクリックするとcountの数が1ずつ増えていく。

### 関数コンポーネントの変数とステート
クラスコンポーネントは状態維持できるが、関数は呼び出される度に変数が初期化される。
常に持っておきたい値はステートとして使用するべきである。

### 複数の関数コンポーネント
以下の用に使用する

```jsx
// 関数コンポーネントの定義
function a() {
  return // 値
}
function b() {
  return // 値
}

function c() {
  // 関数コンポーネントの呼び出し
  <a />
  <b />
  return // 値
}
```

### 値の受け渡し
```jsx
const [msg, setMsg] = useState("This is sample messsage!")
<AlertMessage message={msg} setMsg={setMsg}/>
function AlertMessage(props) {
    // propsで受け取ることができる
    props.message
    props.setMsg()
}
```
ステートを変更すると画面が更新される。（変数を変更しても画面は変わらない）

## 副作用フック
- 値の変更などがあった場合に呼び出される。
- 複数定義可能である。
### 基本形
```js
useEffect( 関数 )
```

関数が実行される条件を記載できる。
```js
useEffect( 関数 ), [ ステート ] )
```
引数のステートが変更された場合のみ関数が実行される。

## 独自フック
ステートフックのように戻り値が「値を得る変数と変更する関数」で固定されておらず、戻り値は複数でも値でも関数でも良い。
#### 基本形
```js
function use○○ (){
  const ステート
  const 関数
  return [ 値 ]
}
```
必ず関数名は`use`から始める。
戻り値は配列を使用する。

## ローカルストレージ
ステートはリロードしたら消えてしまう。
windowオブジェクトの`localStorage`というプロパティを使用することでローカルストレージを使用することが可能である。
キーは値の名前のようなものであり、指定のキーから値を取得することができる。
```js
変数 = wondow.localStorage.getItem(キー)
```
値を指定のキーで保管する。
```js
wondow.localStorage.setItem(キー,値）
```
※`window`は省略可能。

## Next.js
Nextの利点
1. ルーティンングを使用できる。
2. データとのやりとりを行うAPIを簡単に作成できる。
3. `React.js`と異なり、複数ページを持つことができる。 

他にもあるが、本書で取り上げられていたのは上記3つ。

```zsh
npx create-next-app [プロジェクト名]

// TypeScriptを使用する場合
npx create-next-app@latest --ts
```
上記コマンドでプロジェクトを作成できる。
nodeのバージョンが14だとエラーになったので臨機応変にバージョンの変更を行う必要がある。
Next.jsでは内部ではJSXを使用して具体的な「HTMLを使用しているが、HTMLファイルを直接使用することなく、JSファイルで対応する。

### style
基本的に`styles`フォルダ内のCSSに記載してそれを`import`する形が好ましいが、JSXで以下の記述をすることでもCSSを設定可能である。

```jsx
<style jsx>{`
  h1 {
    text-align: center;
  }
`}</style>
```

### header
headerを毎回`index.js`に記載するのは手間である場合は、別ファイルに`Header`の情報を記載して`export`し、必要な場合は`import`して使用することが望ましい。

```js
export default function Header(props) {
  return (
    <Head>
    </Head>
  )
}
```
### Linkコンポーネント
aタグと同じようにリンクを作成することができる。
コンポーネントの内部は`aタグ`でなくとも構わないので`pタグ`や`button`なども使用することができる。

```js
import Link from 'next/link'

<Link href="/">
  <a></a>
</Link>
```

### 子エレメントの受け渡し
```js
export default function コンポーネント名(props) {
  // childrenで使用可能。
  props.children
}
<コンポーネント名>
  子エレメント
</ コンポーネント名>
```

### 画像
画像を扱う場合にもコンポーネント化することで使い回しすることができ、Next.jsらしい使用方法である。
画像を扱う場合に、src属性を使用する際は、publicフォルダのファイル類はサーバー直下にあるように扱われるので、直下にあるファイルは`./`から記載すると良い

```html
<img src=./ファイル名>
```

### API
APIにアクセスする方法はいくつかあるが、代表的なものにfetch APIがある。
```js
fetch( [アクセスするURL] ).then( res => その後の処理 )
```

使用例
ステートを定義しておき、fetchを使用してAPIを呼び出した後のthenメソッド内の処理でステートの関数を使用してAPIの返却値を関数の引数にあててステートの変数を変更している。
```js
const [data, setData] = useState({message:'', data:[]})

fetch(url)
  .then(res=> res.json())
  .then(res=> setData(res))
```
### SWR
インストール
```bash
npm install swr
```

使用例
```js
// JSONデータを取得したい場合
const fetcher = (...args) => fetch(...args).then(res => res.json())
// textデータを取得したい場合
const func = (...args)=> fetch(...args).then(res => res.text())
export default function Home() {
  const { data, error } = useSWR('/data.json', fetcher)
```

next.jsでは、デフォルトで以下のURLにアクセスするとpages/api/hello.jsというファイルにアクセスし、JSONデータを返却してくれる。
```
http://localhost:3000/api/hello
```

#### 特殊な変換
```js
id = req.query.id
↓
{query: {id} = req
```

apiフォルダ下に`[id].jsというファイルを作成すると
パスのid部分を取得することができる。

/〇〇/〇〇
のようなパスの場合は
[...params].jsというファイルを作成し
```js
  const {
    query: {params: [id, item]}
  } = req
```
上記のような配列の形で受け取る。
idやparamsはquery内の名称であり自作することができる。

以上。

## 参考文献
[React.js&Next.js超入門 第2版](https://www.shuwasystem.co.jp/book/9784798063980.html)