【React,useMemo】今日の日付の計算でuseMemoを使用したら無駄な計算を減らせました。

# useMemoの活用
useMemo使ったとき感動したので皆様に共有したくて書きました！

## 作成中のアプリ
筋トレの種類と、その筋トレを回数を記録するアプリ。
UIはこんな感じで、左上の入力フォームに筋トレの種類(腕立て、スクワットなど)を入力して送信すると、コンポーネントが追加されていくようになっています。
![スクリーンショット 2020-11-21 12.33.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/12bc5d07-13b6-3c87-afdd-6823180eef26.png)

未実装ですが、そのコンポーネントの中のフォームで日付と回数を入力して送信すると、その下に記録が溜まっていくイメージです。(UIはこれが最適かどうかはさておき...)



## inputタグの初期値を本日の日付にしたいが再計算が多くなる...
筋トレ記録アプリの作成の中で、日付と筋トレ回数を入力するフォームを作成した。入力するタイミングとして当日中(筋トレ直後)に回数を記録することが多いと思われるため、日付の入力フォームの初期値を当日の日付にしたいと思ったのですが、普通に書くと再計算が多くなり無駄が発生してしまいました...

## useMemo無し
useMemo無しだと、筋トレの種類を追加するたびに、別ディレクトリに書いたtoday.tsのcalculateToday関数が余計に実行されてしまいます。
![スクリーンショット 2020-11-21 12.42.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/a559d20c-b460-6a72-cb3f-3b5ff7c12497.png)

●コード

```Typescript
import React , { FC , useState,useMemo} from 'react';
import Training from '../organisms/training';
import { useForm } from 'react-hook-form';
import { calculateToday } from '../today/today';
import './trainingList.scss';

type training = {
    trainingName: string,
}

const TrainingList: FC = () => {
    const { register , handleSubmit , reset} = useForm<training>();   
    const [ trainingList, setList ] = useState<training[]>([]);
    // const today = useMemo(()=> calculateToday(),[])
    const today = calculateToday()

    const onSubmit = (data: training) => {
        const {trainingName} = data;
        if (!trainingName) {
            alert('トレーニング名を入力してください。') 
            return
        } else if (trainingList.some((name) => name.trainingName === trainingName )) { 
            alert("そのトレーニングは既に登録されています。") 
            reset()
            return
        }

        setList([
            ...trainingList,
            {trainingName:trainingName}   
        ]);

        reset();
    }

    return (
        <div className='container'>
                <form className='input-form' onSubmit={handleSubmit(onSubmit)}>
                    <input name='trainingName' ref={register} placeholder='training name'/>
                    <input type='submit'/>
                </form>
            
            <div className='main'>
                {
                    trainingList.map((list) => {
                        return(
                                <Training
                                    trainingName={list.trainingName}
                                    key={list.trainingName}
                                    today={today}
                                />
                        )
                    })
                }            
            
            </div>
 
        </div>
    )
}

export default TrainingList;
```

## useMemoあり
useMemoを使用すると、calculateToday関数の実行を１回だけにすることができ、下記の検証ツールをご覧いただければ分かる通り、余計な再計算を無くすことができました。
![スクリーンショット 2020-11-21 12.50.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603163/ce592baa-c03f-d314-d586-1d088a277397.png)

コードは上記コードのTrainingListコンポーネントの上から4行目のコードの代わりに、3行目のコメントアウトしている部分を復活させるだけです。

```TypeScript
    
    const today = useMemo(()=> calculateToday(),[])
    // const today = calculateToday()

```

## 最後に
ここまで偉そうに書いてきましたが、業務未経験のため、そもそももっと良い実装方法、UIがあるかもしれませんが、useMemoの活用例の1例として皆様に共有できればと思いました！ご指摘等、厳しい意見お待ちしております！