Reactでフォームを使ってみようシリーズも佳境に差し迫った第4弾。今回はラジオボタンを触ってみます。
時限爆弾の解体ラジオボタンComponent
もはら映画で定番となった、時限爆弾の解体シーンで「青と赤どちらのコードを切るか…」を再現するComponentを作ってみたいと思います。3色のラジオボタンが並んでおりハズレを選択(コードを切断)すると爆発します。
サンプル
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>BomButton</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>
<h1>BomButton</h1>
<p>線を一つ選んで爆弾を解除してください</p>
<img src="./bom1.png">
<div id="root"></div>
<script type="text/babel">
class BomButton extends React.Component {
constructor(props) {
super(props);
this.state = {
radio: [
{cd:'red', name:"赤", checked:false},
{cd:'blue', name:"青", checked:false},
{cd:'green', name:"緑", checked:false}
],
lastclick: null //最後に選択された色を入れる
};
// State内の色の中から抽選を行う
let i = Math.floor(Math.random() * 100) % this.state.radio.length;
this.hit = this.state.radio[i].cd;
// 爆発時の素材を事前ロードしておく
this._preload();
// イベント用メソッド
this.handleRadioClick = this.handleRadioClick.bind(this);
}
/**
* 爆発時の素材を事前ロード
*/
_preload(){
this.se = new Audio('./bomb1.mp3');
this.se.load();
let img = new Image();
img.src = "./bakuhatsu.png";
}
/**
* ラジオボタンをクリック
*/
handleRadioClick(e) {
if( ! confirm('本当にこの線で良いですか?') ){
return(false);
}
let name = e.target.name;
let value = this.state.radio.map( (item)=>{
return({
cd: item.cd,
name: item.name,
checked: (item.cd===name)? true:false
})
});
this.setState({
radio: value
, lastclick: name
});
}
render() {
//----------------
// 当選したら爆発
//----------------
if( this.hit === this.state.lastclick ){
this.se.play();
return <div><img src="./bakuhatsu.png" /></div>
}
//----------------
// 選択肢の表示
//----------------
else{
const radio = this.state.radio;
const listItems = radio.map((r) =>
<label key={r.cd.toString()} style={{color: r.cd}}>
<input
type="radio"
name={r.cd}
value={r.cd}
checked={r.checked}
onChange={this.handleRadioClick} />
{r.name}<br />
</label>
);
return <form>{listItems}</form>
}
}
}
ReactDOM.render(
<BomButton />,
document.getElementById('root')
);
</script>
</body>
</html>
実行結果
※爆発するとSEが再生されます。音量注意。
解説
ラジオボタンの生成方法
render()
内の以下の箇所で生成していますが、基本的に前回のチェックボックスと同じですね。見た目をわかりやすくするためにCSSの指定を行っていますが、こちらは別の機会に解説したいと思います。
const listItems = radio.map((r) =>
<label key={r.cd.toString()} style={{color: r.cd}}>
<input
type="radio"
name={r.cd}
value={r.cd}
checked={r.checked}
onChange={this.handleRadioClick} />
{r.name}<br />
</label>
);
return <form>{listItems}</form>
チェックボックスと異なる点としては、ラジオボタンは1つしかchecked
をtrue
にしてはならないことです。handleRadioClick()
メソッド内でState用データを作成する際の以下の箇所に注目。チェックされたname
が同じ値のときだけtrue
、異なる場合はすべてfalse
としているのがわかると思います。
let value = this.state.radio.map( (item)=>{
return({
cd: item.cd,
name: item.name,
checked: (item.cd===name)? true:false
})
});
書籍
React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)
posted with amazlet at 18.12.24
穴井 宏幸 石井 直矢 柴田 和祈 三宮 肇
翔泳社
売り上げランキング: 139,067
翔泳社
売り上げランキング: 139,067
素材
参考ページ
このブログを応援する
お寄せいただいたお気持ちは全額サーバ代や次の記事を執筆するための原資として活用させていただいております。この記事が参考になった場合などぜひご検討ください。
同じカテゴリの記事
- はじめてのReact #30 「CSSフレームワークを導入する」Material-UI テーマをカスタマイズ編
- はじめてのReact #29 「CSSフレームワークを導入する」Material-UI アイコンと文字スタイル編
- はじめてのReact #28 「CSSフレームワークを導入する」Material-UI グリッド編
- はじめてのReact #27 「CSSフレームワークを導入する」Material-UI インストール編
- はじめてのReact #26 「ルーティングに対応する」設定をJSONにまとめる編 react-router@v5
- はじめてのReact #25 「ルーティングに対応する」認証とリダイレクト編 react-router@v5
- はじめてのReact #24 「ルーティングに対応する」URLパラメーター編 react-router@v5
- はじめてのReact #23 「ルーティングに対応する」基本編 react-router@v5