7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

useStateだらけのコードをスッキリリファクタした話

Last updated at Posted at 2022-03-24

はじめに

  • 個人開発しているアプリでガリガリコードを書いていたら、いつの間にかuseStateだらけになったので、スッキリさせた。
  • ちなみに実際にリファクタしたcommit。

リファクタ前の状況

  • こんなログインフォームを作った。
    スクリーンショット 2022-03-01 22.17.26.png

  • コードはこんなイメージ。実際はもっとstateが多く、コードの見通しが悪い状況でした。
    あくまでイメージなので色々省略しまくっているのはご了承ください。useStateに焦点を当てるためです。

SignIn.jsx
const SignIn = () => {
  const [ mail, setMail ] = useState('')
  const [ pass, setPass ] = useState('')
  const handleMail = (event) => {
    setMail(event.target.value)
  }
  const handlePass = (event) => {
    setPass(event.target.value)
  }

  return (
    <div>
      <p>メールアドレスとパスワードでログイン</p>

      <div>
        <p>メールアドレス</p>
        <input
          value={mail}
          onChange={handleMail}
        />
      </div>

      <div>
        <p>パスワード</p>
        <input
          value={pass}
          onChange={handlePass}
        />
      </div>

        <button>ログインする</button>

        <button>入力内容をクリア</button>
    </div>
  )
}

export default SignIn

複数のuseStateを一つのuseStateにまとめてしまう。

  • ReduxのreducerやHooksのuseReducerの考え方に近いと思います。ちなみに感じたメリット・デメリットは以下のとおり。
    • Vueで例えると複数のdataを一つのstoreにまとめてしまうイメージ。
  • メリット
    • 実装が簡単。
    • 関連性のあるstateを一つのオブジェクトにまとめることで可読性アップ。
    • 関連性の薄いプロパティをまとめてしまうと逆に可読性が落ちるので、その場合は分けたままの方が良い。
  • デメリット
    • イベントハンドラー(ここで言うhandleMail等)はプロパティ毎に必要なので、ここは一つにまとめられない。
      • 【2022/4/5追記】
        コメントでイベントハンドラーを一つにまとめるコードをご提案いただきました。まさにreducerっぽい実装ですね。
    • setter(ここで言うsetUser)の引数が冗長になる。
SignIn.jsx
const SignIn = () => {
  const [ user, setUser ] = useState({
    mail: '',
    pass: ''
  })
  const handleMail = (event) => {
    setUser((user) => {
      return {
        ...user,
        mail: event.target.value
      }
    })
  }
  const handlePass = (event) => {
    setUser((user) => {
      return {
        ...user,
        pass: event.target.value
      }
    })
  }

  return (
    <div>
      <p>メールアドレスとパスワードでログイン</p>

      <div>
        <p>メールアドレス</p>
        <input
          value={user.mail}
          onChange={handleMail}
        />
      </div>

      <div>
        <p>パスワード</p>
        <input
          value={user.pass}
          onChange={handlePass}
        />
      </div>

        <button>ログインする</button>

        <button>入力内容をクリア</button>
    </div>
  )
}

export default SignIn

参考文献

7
2
2

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
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?