当サイトは、アフィリエイト広告を利用しています

useStateの使い方(基本)

作成日:2022月02月28日
更新日:2023年12月04日

ReactHooksのuseStateの基本的な使い方をまとめる。

定義の仕方

useStateをimportする。

jsx
import React, { useState } from 'react'
export default function App()
//const [状態変数, 状態を変更するための関数] = useState(状態の初期値);
const [state,setState] = useState(0)
~
}

state

  • 左辺の1つ目の要素: state の現在の値
  • 任意の名前をつけることが可能。 stateの値はsetStateを通してしか更新できない。

setState

  • 左辺2つ目の要素: state の現在の値を更新するための関数
  • 任意の名前をつけることが可能。 setStateの引数には2種類ある

次のstateを直接引数で受け取る場合

引数の値をそのままstateに設定する

jsx
setState(0)

次のstateを関数で受け取る場合

関数の場合は直前のstateを引数として受け取ることができる

jsx
setState((prevState)=>prevState + 1 )

useState

  • 右辺
  • useStateで初期値を設定する
  • 配列やオブジェクトを設定することもできる。

stateの更新タイミング

useStateは同一のレンダー内では同じ値を保持し続けるため
同一のイベント処理がすべて終了した後にコンポーネントを再レンダリングする。
そして新しくレンダリングされたコンポーネントで更新されたstateを参照できる

stateの値が想定通りに出力できないケース

onClick内でstateの更新前と更新後にconsole出力しているが
同一レンダー内(onClickイベント)であるため値は両方とも
0が出力される。

jsx
import "./styles.css";
import React, { useState } from "react";
const App = () => {
const [count, setCount] = useState(0);
return (
<button
onClick={() => {
console.log(count);
setCount(1);
// 想定では2と出そうだが、同一レンダーないのため
// stateは更新されず0が出力される
console.log(count);
}}
>
カウント1
</button>
);
};
export default App

使い方

useStateの使い方はいくつかの使い方がある。
setStateに設定できるパターンを下記に記載する。
setStateの戻り値でstateが更新されるイメージ。

関数で設定する

setCountに関数を入れることができる。 またstateの値を引数にとれる

jsx
import "./styles.css";
import React, { useState } from 'react'
export default function App() {
//state
const [count,setCount] = useState(0)
return (
<div className="App" >
<div style={{display:"flex"}}>
{/*関数をsetCountに入れる。 */}
<button onClick={() => setCount(count => count + 1)}>
+ 1
</button>
{count}
</div>
</div>
);
}

三項演算子で設定する

changeModeに三項演算子を入れることができる。 またstateの値を引数にとれる

jsx
import "./styles.css";
import React, { useState } from 'react'
export default function App() {
//モード
const [mode,changeMode] = useState("light")
return (
<div className="App" >
<div style={{display:"flex"}}>
<button onClick={() => changeMode((mode)=>mode === "light"?"dark":"light")}>
モード変更
</button>
{mode}
</div>
</div>
);
}

他の関数経由で呼び出す

useStateの値を変更する関数を直接ではなく、別の関数経由で
呼び出すこともできる。
eventの値を使いたい場合や他の処理をはさみたい場合に使用する。

jsx
import "./styles.css";
import React, { useState } from 'react'
export default function App() {
//useState
const [pass, setPass] = useState("");
 //関数内でsetPassを呼び出す
const handleChange = (event) => {
setPass(event.target.value);
};
return (
<div className="App" >
<div style={{flexDirection: "column",textAlign: "start"}}>
  {/* 他の関数経由でsetPassを呼ぶ */}
<input name="pass" value={pass} onChange={handleChange} />
{/* 別の書き方 */}
<input name="pass" value={pass} onChange={(event)=>handleChange(event)} />
<div>
{pass}
</div>
</div>
</div>
);
}

値を入れる

state更新関数に直接値をいれた場合はその値で更新される

jsx
import "./styles.css";
import React, { useState } from 'react'
export default function App() {
//カウンター
const [count,setCount] = useState(0)
//モード
const [mode,changeMode] = useState("light")
const [pass, setPass] = useState("");
 //クリア処理
 //直接値を設定している
const clear = ()=>{
setCount(0)
changeMode("light")
setPass("")
}
const handleChange = (event) => {
setPass(event.target.value);
};
return (
<div className="App" >
<div style={{display:"flex"}}>
<button onClick={() => setCount(count => count + 1)}>
+ 1
</button>
{count}
</div>
<div style={{display:"flex"}}>
<button onClick={() => changeMode((mode)=>mode === "light"?"dark":"light")}>
モード変更
</button>
{mode}
</div>
<div style={{flexDirection: "column",textAlign: "start"}}>
<input name="pass" value={pass} onChange={handleChange} />
<input name="pass" value={pass} onChange={(event)=>handleChange(event)} />
<div>
{pass}
</div>
</div>
<div>
<button onClick={clear}>
クリア
</button>
</div>
</div>
);
}

useStateで連想配列(オブジェクト)や配列を扱う方法については下記記事でまとめています!

参考

React hooksを基礎から理解する (useState編)

React Hooks での form の扱い方

【React】そろそろ技術ブログで setCount(count + 1) と書くのはやめませんか

無限ループする

useStateで下記のような書き方をした場合にエラーが発生する

jsx
import "./styles.css";
import React, { useState } from 'react'
export default function App() {
//カウンター
const [count,setCount] = useState(0)
return (
<div className="App" >
<div style={{display:"flex"}}>
{/*onClickないで */}
<button onClick={setCount(count => count + 1)}>
+ 1
</button>
{count}
</div>
</div>
);
}

無限ループがおこり下記のようなエラー出る

bash
Too many re-renders. React limits the number of renders to prevent an infinite loop.

原因

原因はonClick内でアロー関数を使わずに書いていること

jsx
onClick={setCount(count => count + 1)}

この書き方の場合、onClickでsetCountは呼ばれず、
コンポーネントがrenderされたタイミングでsetCountが呼ばれる。 setStateされたタイミングでrenderされるreactコンポーネントの性質上、
render => setState => render => setState => render ....
と無限ループが起きてしまう。

対応方法

アロー関数を使う、または他の関数経由で呼び出す。

jsx
onClick={() => setCount(count => count + 1)}

参考

【意外とハマる??】Reactで、無限ループに気をつけましょう

新着記事

タグ別一覧
top