目的
- チェックボックスで選択した通りの内容をステートで持つ
- useStateを利用する
例
- チェックボックスを選択し、ステートを更新する
- チェックボックスで選択した通りにステートが更新されていることを、jsonで出力し確認できる
ポイント
- state更新は非同期に実行される。そのため、他のステート更新を前提にした参照をすると思い通りにならないことがある
- HOOKSのuseStateはマージしない。
コード例
App.js
import React, {useState, useEffect} from "react";
import Checkbox from '@mui/material/Checkbox';
const App = (props) => {
// 今回保持するステート。c1~4の4つのチェックボックスの状態をそれぞれ持つ
const [chk, setChk] = useState({
c1:false,
c2:false,
c3:false,
c4:false,
})
// チェックボックスの更新を検知しステートを更新する
const hndlChk1 = (event) => {
// checkBoxのバリューは event.target.checked で取得できる
// ポイント1の箇所
// setChk(別のステートの値を参照して更新したい値); という書き方をすると、更新タイミングが非同期のためうまくいかない
// useStateは、更新値に関数を与えることができる
setChk(prev => {
// 関数のパラメータ(prev) に、前のステートを持っている。その値を使って、更新する新しい値を定義し、returnでstateに返す
console.log("PREV>")
console.log(prev);
console.log("<PREV")
console.log(prev);
// ポイント2の箇所
// useStateはクラスでのstateと異なり、マージされない。そのため、以下のように、stateに持たせる全ての属性を与える必要がある
// 更新したい属性だけをsetStateで与えると、与えたもの意外消える
let data = {
chk1: event.target.checked,
chk2:prev.chk2,
chk3:prev.chk3,
chk4:prev.chk4,
}
return data
});
}
// 以下 hndlChk1と同じことをそれぞれのチェックボックスで実施
const hndlChk2 = (event) => {
setChk(prev => {
console.log("PREV>")
console.log(prev);
console.log("<PREV")
console.log(prev);
let data = {
chk1:prev.chk1,
chk2:event.target.checked,
chk3:prev.chk3,
chk4:prev.chk4,
}
return data
});
}
const hndlChk3 = (event) => {
setChk(prev => {
console.log("PREV>")
console.log(prev);
console.log("<PREV")
console.log(prev);
let data = {
chk1:prev.chk1,
chk2:prev.chk2,
chk3:event.target.checked,
chk4:prev.chk4,
}
return data
});
}
const hndlChk4 = (event) => {
setChk(prev => {
console.log("PREV>")
console.log(prev);
console.log("<PREV")
console.log(prev);
let data = {
chk1:prev.chk1,
chk2:prev.chk2,
chk3:prev.chk3,
chk4:event.target.checked,
}
return data
});
}
return(
<Box>
// onChangeで、チェックボックスの変更イベントを取得する
<FormControlLabel control={<Checkbox onChange={hndlChk1}/>} label="チェックボックス1" />
<FormControlLabel control={<Checkbox onChange={hndlChk2}/>} label="チェックボックス1" />
<FormControlLabel control={<Checkbox onChange={hndlChk3}/>} label="チェックボックス1" />
<FormControlLabel control={<Checkbox onChange={hndlChk4}/>} label="チェックボックス1" />
<Box>
現在のcheckBoxステートの内容 <br></br>
{JSON.stringify(chk)}
</Box>
</Box>
)
}
export default App;