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>
)
}
解決してみれば、なんてことはない修正で解決してしまいました。。