クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【React】独自フックで関数を抽出、全てのツマミが動いた!(ジャンプ率ジェネレーター)

Reactジャンプ率ジェネレーターの続きです。前回はフックでonChangeイベントを設定しました。ようやく一つ目のinput(range)のツマミが動きました。今回は残りの二つも動かします。独自フックで共通した処理を関数として抽出しました。それではいきましょう!

【目次】

※参考:前回記事
【React】フックでonChangeイベントを設定、ツマミが動いた!(ジャンプ率ジェネレーター) - クモのようにコツコツと

※参考:ReactでWebアプリを作るシリーズまとめ
qiita.com

前回のおさらい

フック(useState)を使ってonChangeイベントを設定。ようやく一つ目のinput(type="range")のツマミが動いた。

https://cdn-ak.f.st-hatena.com/images/fotolife/i/idr_zz/20210319/20210319063933.jpg

※参考:【React】フックでonChangeイベントを設定、ツマミが動いた!(ジャンプ率ジェネレーター) - クモのようにコツコツと

今回も残りの二つのツマミも動かしたく、レッツトライ。

残りの2つのツマミも動かす(処理が重複)

まずはuseState設定を追加

  const [lineLength, setLineLength] = useState(35);
  const [lineHeight, setLineHeight] = useState(1.75); // 追加
  const [jumpRate, setJumpRate] = useState(200); // 追加
  • 変数lineHeightsetLineHeightにフックuseState()で初期値1.75を設定
  • 変数jumpRatesetJumpRateにフックuseState()で初期値200を設定

関数changeLineHeight()を定義

  const changeLineHeight = (e: React.ChangeEvent<HTMLInputElement>) => {
    let changeValue: number = Number(e.target.value);
    console.log(changeValue);
    setLineHeight(changeValue);
  };

とりあえず前回changelineLength()関数をコピーして最後に実行する関数をsetLineHeight()に打ち替えている。

※参考:【React】フックでonChangeイベントを設定、ツマミが動いた!(ジャンプ率ジェネレーター) - クモのようにコツコツと


関数changeJumpRate()を定義

  const changeJumpRate = (e: React.ChangeEvent<HTMLInputElement>) => {
    let changeValue: number = Number(e.target.value);
    console.log(changeValue);
    setJumpRate(changeValue);
  };

こちらも同様に最後に実行する関数をsetJumpRate()に打ち替え


行間、ジャンプ率のJSXにdefaultValueonChangeを設定

        <section>
          <h2>行間</h2>
          <p>値:{lineHeight}</p>
          <InputRange type="range" name="range" min="1" max="2.5" defaultValue={lineHeight} onChange={changeLineHeight} step="0.01"></InputRange>
        </section>
        <section>
          <h2>ジャンプ率</h2>
          <p>値:{jumpRate}</p>
          <InputRange type="range" name="range" min="100" max="400" defaultValue={jumpRate} onChange={changeJumpRate}></InputRange>
        </section>
  • 行間 のvaluedefaultValueに変更(値はlineHeight)、onChangeイベントを設定(値はchangeLineHeight
  • ジャンプ率 のvaluedefaultValueに変更(値はjumpRate)、onChangeイベントを設定(値はchangeJumpRate

前回の「行長」のsectionタグと同じ変更。これによってツマミが動くようになるはず。

※参考:【React】フックでonChangeイベントを設定、ツマミが動いた!(ジャンプ率ジェネレーター) - クモのようにコツコツと


Reactを起動してみる

$ npm start

おお!下の2個のツマミも動くようになった! f:id:idr_zz:20210329064629j:plain

しかしこのままだと関数の処理の中身に重複が多いんだよな。。

独自フックで共通の処理を関数として切り出す

重複している部分をどうするか。「独自フック」を使ってみようか。

自分独自のフックを作成することで、コンポーネントからロジックを抽出して再利用可能な関数を作ることが可能です。

※参考:独自フックの作成 – React

独自フックはsetHogeのように関数名の頭にsetをつければいいようだ。


useChangeValue()を作成

  const useChangeValue = (e: React.ChangeEvent<HTMLInputElement>) => {
    let changeValue: number = Number(e.target.value);
    console.log(changeValue);
    return changeValue;
  };
  • これまで作った関数の中の共通している処理を切り出す
  • 最後にreturnchangeValueを返す

ここから先は固有の内容になる。


ChangelineLength()を修正

  const ChangeLineLength = (e: React.ChangeEvent<HTMLInputElement>) => {
    const changeValue = useChangeValue(e);
    setLineLength(changeValue);
  };
  • 関数名をchangeLineLength()からChangeLineLength()に変更
  • 変数changeValueuseChangeValue()を実行(引数はe
  • setLineLength()を実行(引数はchangeValue

二行でコンパクトになった。


なお、関数の一文字目を大文字にしないと下記のエラーになった。

React Hook "useChangeValue" is called in function "changelineLength" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter.

Reactフック「useChangeValue」は、React関数コンポーネントでもカスタムReactフック関数でもない関数「changelineLength」で呼び出されます。 Reactコンポーネント名は大文字で始める必要があります。

大文字にしてReactコンポーネント化する必要があるようだった。


行長のJSXの関数名も変更

        <section>
          <h2>行長</h2>
          <p>値:{lineLength}</p>
          <InputRange type="range" name="range" min="10" max="50" defaultValue={lineLength} onChange={ChangeLineLength}></InputRange>
        </section>
  • 行長のonChangeイベントの中も大文字ChangelineLengthに変更

ブラウザ確認

やった!行長のツマミ、問題なく動いた! f:id:idr_zz:20210330060300j:plain

残り二つにも独自フックを適用

では残りの2つにも独自フックを適用していこう。

ChangeLineHeight()を修正

  const ChangeLineHeight = (e: React.ChangeEvent<HTMLInputElement>) => {
    const changeValue = useChangeValue(e);
    setLineHeight(changeValue);
  };
  • 関数名をchangeLineHeight()からChangeLineHeight()に変更
  • 変数changeValueuseChangeValue()を実行(引数はe
  • setLineHeight()を実行(引数はchangeValue

ChangeJumpRate()を修正

  const ChangeJumpRate = (e: React.ChangeEvent<HTMLInputElement>) => {
    const changeValue = useChangeValue(e);
    setJumpRate(changeValue);
  };
  • 関数名をchangeJumpRate()からChangeJumpRate()に変更
  • 変数changeValueuseChangeValue()を実行(引数はe
  • setJumpRate()を実行(引数はchangeValue

コンパクトになった!


行間、ジャンプ率の関数名も変更

        <section>
          <h2>行間</h2>
          <p>値:{lineHeight}</p>
          <InputRange type="range" name="range" min="1" max="2.5" defaultValue={lineHeight} onChange={ChangeLineHeight} step="0.01"></InputRange>
        </section>
        <section>
          <h2>ジャンプ率</h2>
          <p>値:{jumpRate}</p>
          <InputRange type="range" name="range" min="100" max="400" defaultValue={jumpRate} onChange={ChangeJumpRate}></InputRange>
        </section>
  • 行間のonChangeイベントの中も大文字ChangeLineHeightに変更
  • ジャンプ率のonChangeイベントの中も大文字ChangeJumpRateに変更

ブラウザ確認 f:id:idr_zz:20210330061009j:plain よし、ツマミが3つとも変えられる!

次はこのツマミで変えた数値をCSSスタイルに適用したく!


コード(GitHub)

※参考:GitHub - ryo-i/jump-rate-generator at 6e2d0a65002a3281e4c6a97df3344d4c0789b993

プレビュー(GitHub Pages)

※参考:React App

最後に

ということで、input(range)のツマミが三つとも動かせるようになりましたー。

独自フックは共通化した処理を関数として抽出できていいですね!モジュールを超えて共通化させたい処理にも使えそうに思います。

次回は、input(range)のツマミによって変更した数値をCSSスタイルに適用していきたく思います。ようやく、ジャンプ率ジェネレーターの具現化のフェーズに入っていけそうです。

それではまた!


※参考:ReactでWebアプリを作るシリーズまとめ
qiita.com