質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1220閲覧

React.js でラジオボタンもどきを実装する方法

tarotarosu

総合スコア114

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1グッド

0クリップ

投稿2018/03/16 00:27

前提・実現したいこと

Reactでラジオボタンのようなものを作成したいと考えています。
理想とする挙動はボタンが複数あり、その中の一つをクリックするとボタンの色が変わり(色なりチェックマークなり)、次に違うボタンをクリックするとクリックしたボタンの色が変わり、先ほどクリックしたボタンはデフォルトの色に戻る、といった感じです。

クリックしたボタンの色が変わる適当なサンプルを作成したのですが、このサンプルだと、
クリックしたボタンの色は変わりますが、別のボタンをクリックしても前にクリックしたボタンの色は変化したままです。
理想とする挙動にするためにはクリックされるたびにボタン全部のstatefalseにして再レンダリングし、
クリックしたものだけをtrueにすればいいのだろうなと考えているのですがいまいち実装方法がわかりません...
サンプルからどのように修正すればラジオボタンのような挙動になるのでしょうか?
何か回答を頂けると非常に助かります<(_ _)>

コード

親コンポーネント

jsx

1import React from 'react'; 2import SizeButton from './SizeButton'; 3 4const SizeContainer = (props) => { 5 const { sizes } = props; 6 return ( 7 <div> 8 {sizes.map(size => ( 9 <SizeButton 10 key={size.id} 11 number={size.number} 12 /> 13 ))} 14 </div> 15 ); 16}; 17 18export default SizeContainer;

子コンポーネント

jsx

1import React from 'react'; 2 3export default class SizeButton extends React.Component { 4 constructor(props) { 5 super(props); 6 this.state = { 7 isClicked: false, 8 }; 9 } 10 11 handleClick() { 12 this.setState({ 13 isClicked: true, 14 }); 15 } 16 17 render() { 18 const button = this.state.isClicked 19 ? <div style={{ backgroundColor: '#C8C8C8' }}>{this.props.number}</div> 20 : <div style={{ backgroundColor: '#BA9D5F' }}>{this.props.number}</div>; 21 22 return ( 23 <div onClick={() => this.handleClick()}> 24 {button} 25 </div> 26 ); 27 } 28}

補足情報

<input type="radio">としていないのはボタンを色々とスタイリングしたいという理由もあります。

HayatoKamono👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

イメージ説明

上位のコンポーネントにどのボタンが今、選択されているかのstateを持たせるのがポイントになってきます。

4,5パターンくらい実装方法がありそうですが、一番基礎的なやり方で、かつ、掲載されているコードを元にする方法だと、以下のような感じになると思います。

Demo Code

https://codesandbox.io/s/k96yvnw77v

import React, { Component } from 'react'; import { render } from 'react-dom'; class App extends Component { render() { const sizes = [ { id: 'aaa' }, { id: 'bbb' }, { id: 'ccc' } ] return <SizeContainer sizes={sizes} /> } } class SizeContainer extends Component { constructor(props) { super(props); this.state = { selectedButtonId: null } this.handleButtonClick = this.handleButtonClick.bind(this); } handleButtonClick(event, buttonId) { this.setState({ selectedButtonId: buttonId }) } render() { const { sizes } = this.props; return ( sizes.map((size) => { return ( <SizeButton key={size.id} id={size.id} isSelected={this.state.selectedButtonId === size.id} onClick={this.handleButtonClick} /> ) }) ) } } const SizeButton = ({ id, isSelected, onClick }) => { return ( <div onClick={(event) => onClick(event, id)} style={{ backgroundColor: isSelected ? 'red' : 'blue' }} > {id} </div> ) }; render(<App />, document.getElementById('root'));

投稿2018/03/16 01:10

編集2018/03/16 01:35
HayatoKamono

総合スコア2415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tarotarosu

2018/03/16 04:04

回答ありがとうございます<(_ _)> 回答を参考に実装したところ、理想の挙動を実現できました。 親のコンポーネントにクリックされたコンポーネントのIDをstateとして持たせることが重要だったのですね。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問