【React】useState()でStateを更新できなかった時の対処方法。

July 21, 2020

useState()でStateを更新しようとしたところ、意図した通りに更新することができず、解決に時間がかかってしまいました。 その時の事象や解決方法をまとめていきます。

目次
1.発生した事象とその原因
2.解決方法

発生した事象とその原因

下記は問題のあったコードです。(ブログ用にちょっとコード変えています。)

const Sample: React.FC = props => {
  const [eventId, setEventId] = useState(0)
  const updateEventId = (id: number) => {
    setEventId(id)
    // console.log(eventId) (※2) エラー原因を見つけるために一時的に追加。

    const event = myEvents[eventId]
    console.log(event.title)
  }
  return (
    <form>
      <input 
        value={eventId}
        onChange={(e) => setEventId(e.current.taget.value)}
      />
    </form>
    <p>{eventId}</p>
  )
}

このコードを実行したところ、エラーが発生。
myEvents配列のインデックスに eventIdを使用していたのですが、どうやらそこでエラーが発生した模様。

となると、eventIdが怪しい。ただ、タイポでもないし、Reactの機能をそのまま使用してeventIdを更新している。そんなで、原因の調査に時間がかかってしまいました。試しにconsole.log()eventIdを確認したところ(※2の部分)、ビンゴ。
エラーの原因は、eventIdが「0」のままになってしまっていたことでした。

解決方法

色々試してみた結果、「setEventId()の更新タイミングが原因なのでは?」という推測にたどり着きました。 そこで、ググってみると、同じような事象に遭遇した方を発見!

React Hooks useState state の更新にハマる - かもメモ

やはりsetEventId()の更新タイミングは即時ではないようでした。記事では、更新後のStateを後続処理で使うのではなく、更新後の値を変数にし、それを使用することで解消したとのこと。さすがです。僕もそれに右ならえしました。

具体的な変更内容は、こちら。
変更した内容はとてもシンプルで、myEvents配列のインデックスをeventIdからidに変更しただけです。

const Sample: React.FC = props => {
  const [eventId, setEventId] = useState(0)
  const updateEventId = (id: number) => {
    setEventId(id)
    - const event = myEvents[eventId]
    + const event = myEvents[id] // eventId を id に変更。
    console.log(event.title)
  }
  return (
    <form>
      <input 
        value={eventId}
        onChange={(e) => setEventId(e.current.taget.value)}
      />
    </form>
    <p>{eventId}</p>
  )
}

まとめ

react usestate 002

解決してみれば、なんてことはない修正で解決してしまいました。。