Reactではコンポーネントの中で状態を管理するための機能としてuseStateが用意されています。
jQuery時代は状態管理で大変な思いをしていましたが、「React」によってその大変さから開放されます。
Reactフックを用いると、コンポーネントからReactの機能を使うことができます。
Reactフックで代表的なものが「state」フックです。
stateフック
stateはデータをコンポーネントに記憶させる機能です。
- 入力フォームのテキストや数字などを保持
- チェックボックスで選択されたものを保持
- カウンターの値を保持
そしてこれらのものを更新する機能も備わっています。
useState構文
useState構文は以下のように記述します。これでstateを使う宣言をします。
const [state, setState] = useState(initialState);
state → 現在のstate値
setState → state値を変更(更新)するために使う関数で「更新関数」と呼びます。
initialState → stateの変数の初期値(設定しないとundefindになる)
useStateフックを使うと、state値が変更される毎にReact側で自動的にコンポーネントの再レンダリングを行います。
式の右側のuseState関数が実行されると左側の stateとsetState(更新するための関数)が返されます。
stateの更新方法
useState構文の中にある setState関数が実行されると、コンポーネントの再レンダリングがスケジューリングされます。setState関数はその他の処理がすべて終わった段階で再レンダリングを開始します。タイミングがずれることがあるのでそこは覚えておきましょう。
setState(newState);
setStateで再描画された後は、setStateによって更新された状態がstateになります。
useStateの利用例
const [text, setText] = useState('Hello World!');
const [list, setList] = useState(['apple', 'melon', 'orange']);
const [count, setCount] = useState(0);
const [isOn, setIsOn] = useState(false);
useStateを使ったカウンタープログラム
useStateを使ったカウンタープログラムを作ってみます。
import { useState } from 'react'
import './App.css'
function App() {
const [count,setCount] = useState(0)
//カウンターを一度に3加算する
const pushButton = () => {
setCount((prevCount) => prevCount + 1);
setCount((prevCount) => prevCount + 1);
setCount((prevCount) => prevCount + 1);
}
return (
<>
<h3>Counter(useState)</h3>
<button onClick={pushButton}>count number : {count}</button>
</>
)
}
export default App
下記の例は一見うまく動きそうですが、一度に1しか加算されません。countは定数で、更新関数(setCount)はその他の処理がすべて終わった段階で再レンダリングを実行するという仕組みだからです。
import { useState } from 'react'
import './App.css'
function App() {
const [count,setCount] = useState(0)
//カウンターを一度に3加算する
const pushButton = () => {
setCount(count + 1)
setCount(count + 1)
setCount(count + 1)
}
return (
<>
<h3>Counter(useState)</h3>
<button onClick={pushButton}>count number : {count}</button>
</>
)
}
export default App
この例だとスタートはcount = 0です。 useState(0)でデフォルト値を0に指定しているため。
ボタンをクリックして pushButton関数が実行されると
まず1回目の setCount(count + 1)は setCount(0 + 1) = 1 となります。他にも処理が残っているのでここではcountは0のままです。
2回目のetCount(count + 1)も setCount(0 + 1) = 1 となります。3回目も同様。
よって、3つの処理が終わった時点で結果は setCount(0 + 1) = 1 この時点でcountが1となりそれが描画されます。
FormのInputでUseStateを使う方法
フォームに本の名前と価格を入力する2つのフォームを作り、入力した値がその下に表示されるようにしてみます。左側が本の名前、右側が本の値段です。
画面イメージ↓
App.js
function App() {
return (
<div>
<Test />
</div>
);
}
Test.js
import React, { useState } from 'react'
const Test = (props) => {
//useState構文 const[現在の値,更新関数] =useState(初期値)
//初期値は name , price の2つ。それぞれ値は空。
const [book, setBooks] = useState({ name: '', price: '' })
return (
<div>
<form>
{/* ② book name のインプットボックス */}
<input type='text' value={book.name}
onChange={evt => setBooks({ ...book, name: evt.target.value })} />
{/* ③ book price のインプットボックス */}
<input type='text' value={book.price}
onChange={evt => setBooks({ ...book, price: evt.target.value })} />
</form>
{/* ④ 入力された値を表示 */}
<div>book name : {book.name}</div>
<div>book price : {book.price}</div>
</div>
)
}
export default Test
まず①の右辺、初期値「空」が④にセットされます。インプットに文字を入力するとリアルタイムでsetBooks(更新関数)が実行され、値がbook(変数:現在の値)に渡されます。
それが表示部分に反映されます。上記画像の緑矢印の流れをイメージで覚えると良いです。
ReactのHooksだとこんな簡単にリアルタイム表示が実現できてしまいます。