当サイトは、アフィリエイト広告を利用しています
useStateの使い方のサンプルをいくつかまとめておく。
useStateの基本的な使い方にについては下記記事で紹介しています
useStateのstateをオブジェクトにすることができる。 初期値設定時にオブジェクトを設定する。
//オブジェクトのkeyが決まってる場合const [form, setForm] = useState({ email: '', password: '' });//何もなしでも可能const [form, setForm] = useState({});
戻り値を新規オブジェクトで返却する。
戻り値のオブジェクト内で引数(prevState)でもらった更新前のstateを
スプレッド構文で展開する。
展開後にeventの値で同じkeyのvalueを更新するイメージ。
※実際は直前のstateから新規オブジェクトを作っている。
イベント発生時に直接、state更新関数を呼ぶ。
eventの値をstate更新関数で使用してたい場合は下記のようにonChange内の引数にイベントを設定した
アロー関数の中でstate更新関数を呼ぶようにする。
※state更新関数で引数にとれるのは直前のstateのみのため
import "./styles.css";import React, { useState } from 'react'export default function App() {const [form, setForm] = useState({});return (<div><label>メールアドレス:<inputname="email"type="email"onChange={(e) => {setForm((prevState) => {return {...prevState,[e.target.name]: e.target.value,}})}}/></label>{form.email}</div>);}
handleChange内でstate更新関数を使う。
イベント時にはhandleChangeを呼ぶようにする
import "./styles.css";import React, { useState } from 'react'export default function App() {const [form, setForm] = useState({});const handleChange = (e) => {setForm((prevState) => {return {...prevState,[e.target.name]: e.target.value,};});};return (<div><label>メールアドレス:<inputname="email"type="email"onChange={handleChange}/></label>{form.email}</div>);}
初心者でもわかるReact Hook のuseStateを使い方
useStateのstateに配列を設定することができる。 初期値設定時に配列を設定する。
//useStateの初期値const initialState = ["baseboll","soccer","basketball","volleyball","tennis"];// useStateconst [sports, setSports] = useState(initialState);
state更新に関してはオブジェクト同様にevent内に直接記述することや
他の関数経由で呼ぶことできる。
※オブジェクトの場合とほぼ同じようなコードになるのでここでは省略
setStateで直前のstateをスプレッド構文で展開した分 + 追加項目で新しい配列を作るようする
import { useState, useRef } from "react";export default function App() {//useStateの初期値const initialState = ["baseboll","soccer","basketball","volleyball","tennis"];// useStateconst [sports, setSports] = useState(initialState);//useRefでinputと紐づけconst inputElement = useRef(null);// 追加処理//現状のstateをスプレッド構文で展開した分 + 追加項目で新しい配列を作る//返却値として新しい配列を返すconst addSports = () => {setSports([...sports, inputElement.current.value]);};return (<div className="App"><h1>Sample</h1><input type="text" name="atext" ref={inputElement} /><button onClick={addSports}>追加する</button><ul>{sports.map((sport) => {return <li>{sport}</li>;})}</ul></div>);}
state配列の値を更新したい場合は、setSportsでラムダ式のmapを使って
配列内の更新対象を更新した新しい配列を設定するようにする。
※mapは配列に任意の処理をした新しい配列を戻り値として返すため
import { useState, useRef } from "react";export default function App() {//useStateの初期値const initialState = ["baseboll","soccer","basketball","volleyball","tennis"];// useStateconst [sports, setSports] = useState(initialState);//useRefでinputと紐づけconst inputElement = useRef(null);const taregetInputElement = useRef(null);const updateInputElement = useRef(null);// 追加処理//現状のstateをスプレッド構文で展開した分 + 追加項目で新しい配列を作る//返却値として新しい配列を返すconst addSports = () => {setSports([...sports, inputElement.current.value]);};//更新処理//mapで更新対象を更新した新しい配列を返却するconst updateSportsList = () => {setSports(sports.map((sport) =>sport === taregetInputElement.current.value? updateInputElement.current.value: sport));};return (<div className="App"><h1>Sample</h1><input type="text" name="atext" ref={inputElement} /><button onClick={addSports}>追加する</button><ul>{sports.map((sport) => {return <li>{sport}</li>;})}<div><label>更新対象</label><input type="text" name="atext" ref={taregetInputElement} /></div><div><label>更新項目</label><input type="text" name="atext" ref={updateInputElement} /></div><button onClick={updateSportsList}>更新する</button></ul></div>);}
state配列の値を削除したい場合は、setSportsでラムダ式のfilterを使って
配列内の削除対象を除いた新しい配列を設定するようにする。
import { useState, useRef } from "react";export default function App() {//useStateの初期値const initialState = ["baseboll","soccer","basketball","volleyball","tennis"];// useStateconst [sports, setSports] = useState(initialState);//useRefでinputと紐づけconst inputElement = useRef(null);const taregetInputElement = useRef(null);const updateInputElement = useRef(null);// 追加処理//現状のstateをスプレッド構文で展開した分 + 追加項目で新しい配列を作る//返却値として新しい配列を返すconst addSports = () => {setSports([...sports, inputElement.current.value]);};//更新処理//mapで更新対象を更新した新しい配列を返却するconst updateSportsList = () => {setSports(sports.map((sport) =>sport === taregetInputElement.current.value? updateInputElement.current.value: sport));};// 削除処理//filterで削除対象以外を除いた新しい配列を返却するconst delSportsList = () => {setSports(sports.filter((sport) => sport !== inputElement.current.value));};return (<div className="App"><h1>Sample</h1><input type="text" name="atext" ref={inputElement} /><button onClick={addSports}>追加する</button><button onClick={delSportsList}>削除する</button><ul>{sports.map((sport) => {return <li>{sport}</li>;})}<div><label>更新対象</label><input type="text" name="atext" ref={taregetInputElement} /></div><div><label>更新項目</label><input type="text" name="atext" ref={updateInputElement} /></div><button onClick={updateSportsList}>更新する</button></ul></div>);}
基本的にstateに配列やオブジェクトを設定している場合、追加、削除、更新をする場合は
スプレッド構文やラムダ式(mapやfilterなど)を利用して新しく作りなおすようにする。
理由としては、reactではstateやpropsの値が変化した時にコンポーネントの再描画が行われるため
pushやspliceでは再描画されないため。
※Objects.isメソッドで判定しているらしい。