useStateを使って値をセットしたんだけど値が更新されないよ・・・
どうして更新されないの?
useStateには値が更新されるタイミングあるよ!
どのように対処したらいいか解説するね!
useStateとは?
useStateは状態管理をするフックです。
状態変数と状態変数を更新する関数を返します。
const [状態を入れる変数, 状態を変更する関数] = useState(状態の初期値);
値が更新されない記述
「+」をクリックするとcount変数に1を増やしていくplus関数があります。
この関数の中でcountをログで確認すると何が表示されるでしょうか。
ログを表示する前に「count + 1」をしているので初期値0に1が加算されて「1」が表示されそうですが、「0」が表示されてしまいます。
import React, { useState } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
const plus = () => {
setCount(count + 1);
console.log(`count: ${count}`); // この時点では「count」は更新されていない
}
return (
<div>
<p>カウント: {count}</p>
<button onClick={plus}>+</button>
</div>
);
}
なぜこの記述だと値が更新されないのか詳しく解説していきます。
値が更新されない理由とは?
なぜsetCount(count + 1)
をして1を加算しているのにcount変数は更新されていないのでしょうか。
それはuseStateの値が更新されるタイミングがあるからです。
useStateの値が更新されるタイミングは再レンダリングされた後になります。
ここでは関数が呼び出された後に再レンダリングされるので、関数呼び出し後に値が更新されます。
そのため関数内でcount変数をログで確認したとしても、まだ更新は反映されてはいません。
console.log(`count: ${count}`); // countは0のまま
値が更新されるのは関数が呼び出された後なので、画面上に表示するときには値が更新されています。
<p>カウント: {count}</p> {/* countは1になる */}
更新した値を表示する方法
「再レンダリングされた後」にしか更新されないと解説しましたが、再レンダリングされる前に更新した値を取得したいケースは多くあると思います。
そこで、更新した値を表示する2つの方法について解説していきます。
- 別の変数で値を保持する
- set関数の第1引数を使う
別の変数で値を保持する方法
まずは別の変数を使って値を保持する方法です。
関数内で変数を定義して、その変数に対して1を加算した値を保持しておきます。
set関数でその変数の値を指定して更新を行います。
関数内で別の変数に値を保持しておくシンプルな方法です。
import React, { useState } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
const plus = () => {
const tmpCount = count + 1;
setCount(tmpCount);
console.log(`count: ${tmpCount}`);
}
return (
<div>
<p>カウント: {count}</p>
<button onClick={plus}>+</button>
</div>
);
}
set関数の第1引数を使う方法
続いてset関数の第1引数を使う方法です。
useStateのset関数に第1引数を渡すと前回の値が入ります。
setCount((前回の値) => ...)}
この引数には常に最新の値が入っているため、最新の値を取得するときはこの引数を使います。
import React, { useState } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
const plus = () => {
setCount(count + 1);
setCount((preCount) => {
preCount + 1;
console.log(`count: ${preCount}`);
})
}
return (
<div>
<p>カウント: {count}</p>
<button onClick={plus}>+</button>
</div>
);
}
まとめ
- useStateはstateを管理するためのフック
- useStateの値が更新されるタイミングは再レンダリングされた後
- 更新した値を表示するには「別の変数で値を保持する」、「set関数の第1引数を使う」の2つの方法がある