Nextjs,React勉強記~とらハック氏の動画メモ~



下記のYouTube動画で学んだ自分用メモを残す

# 参照
- React講座基礎編
    - https://youtube.com/playlist?list=PLX8Rsrpnn3IWPoM7-1YPDksRRkamRY25k
- Next.js講座
    - https://youtube.com/playlist?list=PLX8Rsrpnn3IUGEyanrHYGjY1WOzNe7Jd-

# Nextjs

pre-rendering

ブラウザに渡す前または渡す際にサーバー側で
HTML,JS,CSSのファイルを生成してしまう事

メリット
- SEO
- 高速な表示


pre-renderingの方式(**いつ**HTMLファイルを生成するかがポイント)
- static generation→ビルドする時に生成する。使用のたびに再利用する
- server-side generation→リクエストに応じて生成する。

ページ内でもフォームごとに方式を切り替えることが可能

next.jsはstatic generation推しみたい


# React
- componentの意義
    - 親→子へpropsを通してパラメータを渡す

    親:App.jsx
        子:Article.jsx

子には記事のフォーマットが記載されている。

親のApp.jsxに渡すprops(パラメータ)を記載する。

【メリット】
記事によってタイトルなどは異なるが、フォーマットは同様なので、変更箇所は親のApp.jsxだけで良い。


【ポイント】
1. 1コンポーネント=1ファイル
    1. 責務を明確に
    1. 再利用しやすい
1. 1ファイル=1モジュール
    1. 必要な時に必要なモジュールのみを読み込む
1. exportの種類
    1. default export
        1. 公式推奨
        1. 1ファイル=1export
        1. 名前は'default'でexportされる
    1. 名前付きexport
        1. 1ファイルから複数モジュールをexportしたいとき
        1. 名前をつけてexportできる
        1. エントリポイントで使用される
     

エントリポイント：インポートをまとめたファイル

default exportの例
ex1)アロー関数
`const Title = (props) => {
    return <h2>{props.title}</h2>
};
export default Title;
`
ex2)名前付き関数
`export default function Title(props){
    return <h2>{props.title}</h2>
};
`

名前付きexportの例
ex1)アロー関数
`export const getWild = () => {
    console.log('Get Wild and touch')
};
`
ex2)エントリポイント
`export {default as Article} from './Article'`
`export {default as Content} from './Content'`




## react hooks(便利なメソッド達)

### Hooksとは
- Hooks=*クラスコンポーネントの機能に接続する*
- 関数コンポーネントでも使えるようになった機能の
    - state:コンポーネント内で状態を管理する
    - ライフサイクル:コンポーネントの時間の流れに基づく

### usestate
#### 構文
- 宣言
    - `const [state, setState] = useState(initialState)`
- 更新
    - `setState(newState)`
- 説明
    - state
        - 現在の状態
    - setState
        - 更新関数
    - initialState
        - 初期値
    - newState
        - 新しい値

---

- コンポーネントの値を書きかえたい
    - コンポーネント内の要素をDOMで直接変更←←←**NG**
    - 新しい値を使用して再描画(再レンダリング)←←←**GOOD**
- コンポーネントの再描画のタイミング
    - stateが変更された時
    - propsが変更された時

#### propsとstate

- **両者とも再描画のきっかけ**
    - props:**引数**のようにコンポーネントに渡される値
        - 親to子
    - state:**コンポーネントの内部**で宣言・制御される値
        - ＊＊＊
    - steteをpropsに渡すパターンが多い
        - 更新関数は関数化してpropsに渡す
        - 関数の渡し方の**注意**
            - **コールバック関数**か**関数自体**を渡す
            - porpsに渡す時に関数を実行しない
            - **OK**
                - `<PublishButton isPublished={isPublished} onClick={publishArticle} />`
                - `<PublishButton isPublished={isPublished} onClick={() => publishArticle()} />`
            - **NG**
                - `<PublishButton isPublished={isPublished} onClick={publishArticle()} />`

#### prevState

- ちゃんと前の状態を見に行く
    - ＊＊＊

---


##### カウンターの例

###### いいカウンター


    import React, {useState, useEffect} from 'react';
    const Counter = () => {
    const [count, setCount] = useState(0)
    const countUp = () => {
        setTimeout(() => setCount(prevState => prevState + 1), 1000)
    }
    
    const countDown = () => {
        setCount(prevState => prevState - 1)
    }

    return (
        <div>
            <p>
                good counter <br/>
                current count num: {count}
            </p>
            <button onClick={countUp}>UP</button>
            <button onClick={countDown}>Down</button>
        </div>
        );
    }
    export default Counter;



###### 悪いカウンター
 

    import React, {useState} from 'react';
    
    const BadCounter = () => {
        const [count, setCount] = useState(0)
        const countUp = () => {
            setTimeout(() => setCount(count + 1), 1000)
        }
        
        const countDown = () => {
            setCount(count - 1)
        }
    
        return (
            <div>
                <p>
                    bad counter <br/>
                    current count num: {count}
                </p>
                <button onClick={countUp}>UP</button>
                <button onClick={countDown}>Down</button>
            </div>
        );
    }
    
    export default BadCounter;

#### ライフサイクル

- コンポーネントに関する概念
- 3種類
    - Mounting
        - コンポーネントが配置される期間
    - Updating
        - コンポーネントが変更される期間
    - Unmounting
        - コンポーネントが破棄される瞬間
---


#### useEffect

- useEffectとは
    - 関数コンポーネントで使われる副作用フック
        - 副作用:レンダリングによって引き起こされる処理

- ユースケース
    - APIやDBから非同期通信でデータを取得する
    - 特定の値が変わったらデータを再取得する
---

引数に配列を使用。配列の中身が変更されると処理が実行される

    //毎回レンダリングされる
    useEffect(() => {
        console.log("Current count is......",count)
    })

    // 初回レンダリングのみ実行される
    useEffect(() => {
        console.log("Current count is......",count)
    },[])

    // triggerが変更されるたびに実行される
    useEffect(() => {
        console.log("Current count is......",count)
    },[trigger])

    // trigger1 or trigger2が変更されるたびに実行される
    useEffect(() => {
        console.log("Current count is......",count)
    },[trigger1,trigger2])


###### クリーンアップ

API等の処理が必要なくなったらクリーンアップ関数を使って掃除する

    import {useState,useEffect} from  'react';
    
    const ToggleButton = () => {
        const [open, setOpen] = useState(true)
    
        const toggle = () => {
            setOpen(prevState => !prevState)
        }
    
        useEffect(() => {
            console.log('Current state is ',open)
            if (open){
                console.log('Subscribe database......')
            }
            return () => {
                console.log('Unsubscribe database.....')
            }
        })
    
        return (
            <button onClick = {toggle}>
                {open ? 'OPEN': 'CLOSE'}
            </button>
        );
    };
    
    export default ToggleButton;



##### 非同期処理
- APIやDBからデータを取得(fetch)する
- ポイント
    - async,awaitを使って書く
    - ＊＊＊

##### APIを使用
githubAPIを使用して    

    import { useEffect, useState } from "react";
    import {Article,BadCounter, Counter,ToggleButton, TextInput, PublishButton} from "./components/index";
    
    function App() {
      const [name, setName] = useState()
      const [id, setId] = useState('deatiger')
      const ids = ['deatiger', 'gaearon', 'aws', 'google', 'facebook']
      const getRandomId = () => {
        const _id = ids[Math.floor(Math.random() * ids.length)]
        setId(_id)
      }
    
      useEffect(() => {
        fetch(`https://api.github.com/users/${id}`)
          .then(res => res.json())
          .then(data => {
            console.log(data)
            setName(data.name)
          })
          .catch(error =>{
            console.error(error)
          })
      },[id])
      return (
        <div>
          <p>{id}の、GitHub上の名前は{name}です。</p>
          <button onClick={getRandomId}>IDを変更</button>
        </div>
      );
    }
    
    export default App;


### useReducer

https://qiita.com/seira/items/2fbad56e84bda885c84c

useStateをまとめて、すっきりさせることが出来る

##### Tips

- バッククオーテーション内でjavascriptを書ける
    - ~ `aiue${変数}okaki' ~


- ...で配列の要素を展開できる。

https://typescript-jp.gitbook.io/deep-dive/future-javascript/spread-operator