LoginSignup
0
1

More than 3 years have passed since last update.

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

Posted at

useMemoの活用

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

作成中のアプリ

筋トレの種類と、その筋トレを回数を記録するアプリ。
UIはこんな感じで、左上の入力フォームに筋トレの種類(腕立て、スクワットなど)を入力して送信すると、コンポーネントが追加されていくようになっています。
スクリーンショット 2020-11-21 12.33.06.png

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

inputタグの初期値を本日の日付にしたいが再計算が多くなる...

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

useMemo無し

useMemo無しだと、筋トレの種類を追加するたびに、別ディレクトリに書いたtoday.tsのcalculateToday関数が余計に実行されてしまいます。
スクリーンショット 2020-11-21 12.42.08.png

●コード

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関数の実行を1回だけにすることができ、下記の検証ツールをご覧いただければ分かる通り、余計な再計算を無くすことができました。
スクリーンショット 2020-11-21 12.50.05.png

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


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

最後に

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

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1