★前回の記事
続いて、<input>
を<TextField>
に変更します。
inputのref
<input>
でref
属性を使用している場合は、<TextField>
に変更する際にいくつか注意点があります。
ref
属性をinputRef
属性に変更する<input>
への参照を保存する変数はクラス変数にする
上記の変更も同時に行う必要があります。また、クラス変数を使用するため、関数コンポーネントから、React.Componentを拡張したクラスへの変更を行います。
Material-UIのTextFieldを使用する
ソースコードを書き換えていきます。
src/containers/todos/AddTodo.js
({/* xxx */}
のコメントは実行前に削除してください)
import TextField from '@material-ui/core/TextField' // #1 class AddTodo extends React.Component { // #2 render() { // #3 const {uid, dispatch} = this.props // #4 // let input は削除 // #5 return ( <div> <form onSubmit={ e => { e.preventDefault() if (!this.inputElement.value.trim()) { // #6 return } dispatch(addTodo(uid, this.inputElement.value)) // #7 this.inputElement.value = '' // #8 }} > <TextField // #9 inputRef={node => { // #10 this.inputElement = node // #11 }} /> {' '} {/* #12 */} <Button variant="contained" color="secondary" type="submit"> タスクを追加 </Button> </form> </div> ) } }
- TextFieldをmaterial-uiからインポートします(#1)。
- AddTodoコンポーネントを関数コンポーネントからReact.Componentを拡張したクラスに変更します(#2)。
- クラスに変更したので、
render
メソッドを定義し、propsの受け取りかたを変更します(#3, #4)。 - ローカル変数
input
は使用しないので、削除します(#5)。 input.value
をthis.inputElement.value
に変更します(#6, #7, #8)。<input>
を<TextField>
に変更します(#9)。ref
属性をinputRef
属性に変更します(#10)。TextField
内で描画される<input>
のref
に、inputRef
で指定した内容が渡されます。- 参照の保存先を、ローカル変数からメンバ変数に変更します(#11)。ローカル変数に保存すると、AddTodoのコンポーネントが再描画される際に、ローカル変数
input
がundefined
で再度初期化される一方、inputRef
に指定した関数は実行されず、<input>
の内容が取得できないためです。詳しくは参考のリンク先をご覧ください。 <TextField>
と<Button>
の間に空白を入れます(#12)。見た目の調整です。
実行結果
書き換えた結果は以下のようになります。
タスクの入力部分がMaterial-UIのものになりました。デフォルトではテキストの入力フォームは下線のみ描画されます。
タスクの追加も正常に行えます。
以上でMaterial-UIのTextFieldへの変更が完了しました。
参考
- Text Field React component - Material-UI
- Material-UIのTextFieldでrefを使う - Javaエンジニア、React+Redux+Firebaseでアプリを作る
- ReactでinputRef使用時、参照を保持する変数がundefinedになった原因と対処法 - Javaエンジニア、React+Redux+Firebaseでアプリを作る
★次回の記事
★目次