🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

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

Q&A

解決済

1回答

11831閲覧

Material-UIのTextFieldコンポーネントの初期値を消すことができない

action_moto

総合スコア8

Material-UI

Material-UIは、Material Designを利用可能なオープンソースのReact向けUIコンポーネントキットです。

React.js

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

0グッド

0クリップ

投稿2021/01/02 03:39

編集2021/01/02 05:47

<現状>
現在、Material-UIのTextFieldコンポーネントの初期値を消すことができなく、困っています。
defaultValueをセットしてみたり色々試しましたが、うまく行きません。宜しくお願いします。

<実現したいこと>
①Material-UIのTextFieldで数値を扱いたい
②Material-UIのTextFieldの初期値を0にセットしたい
③Material-UIのTextFieldの値を削除して、新規の値を入力したい
④Material-UIのTextFieldの値を0にするクリアボタンを作成したい

<コード>

js

1import React from 'react' 2import TextField from '@material-ui/core/TextField' 3 4export default class App extends React.Component { 5 constructor(props) { 6 super(props) 7 this.state = { 8 d1: 0 9 } 10 } 11 12 handleChange = (event) => { 13 this.setState({ 14 [event.target.name]: Number(event.target.value) 15 }) 16 } 17 18 handleClear = () => { 19 this.setState({ 20 d1: 0 21 }) 22 } 23 24 render(){ 25 <div> 26 <TextField 27 type="number" 28 name="d1" 29 InputLabelProps={{ 30 shrink: true, 31 }} 32 margin="dense" 33 value={this.state.d1} 34 onChange={this.handleChange} 35 /> 36 <Button onClick={ this.handleClear }> 37 クリア 38 </Button> 39 </div>

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

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

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

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

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

itepechi

2021/01/02 06:15

削除キー/バックスペースキーを押下してもテキストフィールドの中に0が残り続けて困っている、という認識で合っていますか?
action_moto

2021/01/02 06:18

@itepechi その通りです。わかりにくくてすいません。0が消せず、5を入力すると05となってしまいます。
action_moto

2021/01/02 06:29

@hoshi-takanori できました!ありがとうございます。bindに対する理解が不十分なようなので、勉強します!
action_moto

2021/01/02 06:29

@itepechi ありがとうございます。
action_moto

2021/01/02 06:56

@hoshi-takanori @itepechi 一度、バックスペースキーでテキストフィールドの中の0が消えたのですが、もう一度やり直してみたところ、0が消えません。先程のできたを訂正します。
hoshi-takanori

2021/01/02 07:15

@itepechi そうですね。見落としてました。ご指摘ありがとうございます。 @action_moto クリアした時に 0 が残るのが問題なら、handleClear で d1 を 0 にしているのが原因なので、空文字列にすればいいのでは。
hoshi-takanori

2021/01/02 07:25

また、テキストフィールドが 0 のときにバックスペースを押しても消えないのは、event.target.value は空文字になるけど、handleChange でそれを数値に変換してるために 0 になるからでしょうね。
guest

回答1

0

ベストアンサー

Reactのコンポーネントには__controlled__と__uncontrolled__と呼ばれる2種類の状態が存在します。

  • controlled
    要素がstateにより制御されている
  • uncontrolled
    要素が制御されていないか、refを介して直接DOMを操作されている

質問文のテキストフィールドにはvalue={this.state.d1}という属性が設定されているため、要素が__controlled__の状態(stateにより制御されている状態)になっています。__controlled__の状態ではDOMはstateの変更を受けますが、stateはDOMの変更を受けません。そのため、例えばonChangeで変更イベントをキャッチし、handleChange()でstateにイベントから受け取った値を入れ、stateの内容をもう一度DOMに戻すといった手順を踏む必要があります。言い方を変えれば、画面に表示されている数字はテキストフィールドに入力した結果ではなく、stateを変更した結果ということになります。

stateの初期化やhandleChange()を参照するとd1の型は常にnumberですが、numberには""に相当する状態が存在しないため、型変換(Number())の際に0に変更されます。テキストフィールドの内容を消そうとすると0が表示される理由はここにあります。

この問題を解決するためにはテキストフィールドと結びつける値を型がstringの値に変更します。以下は直感的な操作を重視した実装の一例です:

js

1import React from "react"; 2import TextField from "@material-ui/core/TextField"; 3import Button from "@material-ui/core/Button"; 4 5export default class App extends React.Component { 6 constructor(props) { 7 super(props); 8 this.state = { 9 d1: { 10 number: 0, 11 rawString: "0", 12 }, 13 }; 14 } 15 16 handleChange = (event) => { 17 const name = event.target.name; 18 const rawString = event.target.value; 19 const number = Number.parseInt(rawString, 10); 20 21 if (Number.isNaN(number)) { 22 // NaNの場合はnumberを更新しない 23 this.setState({ 24 ...this.state, 25 [name]: { 26 ...this.state[name], 27 rawString, 28 }, 29 }); 30 } else { 31 // NaNでない場合は数字を変更する 32 this.setState({ 33 ...this.state, 34 [name]: { 35 number, 36 rawString: number.toString(), // 文字も数字から作成する 37 }, 38 }); 39 } 40 }; 41 42 handleClear = () => { 43 this.setState({ 44 d1: { 45 number: 0, 46 rawString: "0", 47 }, 48 }); 49 }; 50 51 render() { 52 return ( 53 <div> 54 <TextField 55 type="number" 56 name="d1" 57 InputLabelProps={{ 58 shrink: true, 59 }} 60 margin="dense" 61 value={this.state.d1.rawString} 62 onChange={this.handleChange} 63 /> 64 <Button onClick={this.handleClear}>クリア</Button> 65 <p> 66 数字は<code>{this.state.d1.number}</code> 67 </p> 68 </div> 69 ); 70 } 71}

投稿2021/01/02 08:16

編集2021/01/02 08:39
itepechi

総合スコア248

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問