当サイトは、アフィリエイト広告を利用しています
ReactHooksのuseStateの基本的な使い方をまとめる。
useStateをimportする。
import React, { useState } from 'react'export default function App()//const [状態変数, 状態を変更するための関数] = useState(状態の初期値);const [state,setState] = useState(0)~}
引数の値をそのままstateに設定する
setState(0)
関数の場合は直前のstateを引数として受け取ることができる
setState((prevState)=>prevState + 1 )
useStateは同一のレンダー内では同じ値を保持し続けるため
同一のイベント処理がすべて終了した後にコンポーネントを再レンダリングする。
そして新しくレンダリングされたコンポーネントで更新されたstateを参照できる
onClick内でstateの更新前と更新後にconsole出力しているが
同一レンダー内(onClickイベント)であるため値は両方とも
0が出力される。
import "./styles.css";import React, { useState } from "react";const App = () => {const [count, setCount] = useState(0);return (<buttononClick={() => {console.log(count);setCount(1);// 想定では2と出そうだが、同一レンダーないのため// stateは更新されず0が出力されるconsole.log(count);}}>カウント1</button>);};export default App
useStateの使い方はいくつかの使い方がある。
setStateに設定できるパターンを下記に記載する。
setStateの戻り値でstateが更新されるイメージ。
setCountに関数を入れることができる。 またstateの値を引数にとれる
import "./styles.css";import React, { useState } from 'react'export default function App() {//stateconst [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の値を引数にとれる
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の値を使いたい場合や他の処理をはさみたい場合に使用する。
import "./styles.css";import React, { useState } from 'react'export default function App() {//useStateconst [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更新関数に直接値をいれた場合はその値で更新される
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】そろそろ技術ブログで setCount(count + 1) と書くのはやめませんか
useStateで下記のような書き方をした場合にエラーが発生する
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>);}
無限ループがおこり下記のようなエラー出る
Too many re-renders. React limits the number of renders to prevent an infinite loop.
原因はonClick内でアロー関数を使わずに書いていること
onClick={setCount(count => count + 1)}
この書き方の場合、onClickでsetCountは呼ばれず、
コンポーネントがrenderされたタイミングでsetCountが呼ばれる。
setStateされたタイミングでrenderされるreactコンポーネントの性質上、
render => setState => render => setState => render ....
と無限ループが起きてしまう。
アロー関数を使う、または他の関数経由で呼び出す。
onClick={() => setCount(count => count + 1)}