TextFieldでrefを使う
Material-UI導入時、inputをTextFieldに置き換える時に、多くの属性は<input>
を<TextField>
に置き換えた際そのままでよいのですが、refはそのままにすると動きません。ref
をinputRef
に変更する必要があります。
変更前
const AddTodo = ({dispatch}) => { let input; // 略 return ( <input ref={node => { input = node }} /> ) }
変更後
import TextField from '@material-ui/core/TextField' class AddTodo extends React.Component { render() { return ( <TextField inputRef={node => { this.inputElement = node }} /> ) } }
<TextField>
は<input>
そのものではないので、TextFieldにrefを指定しても動きません。代わりに、inputRef
プロパティを渡して、(TextFieldから子孫コンポーネンントにバケツリレーして、)<input ref={props.inputRef}>
としてrefを設定します。
同様に、inputにプロパティ(readonlyやstepなど)を渡す場合にも、inputProps
にオブジェクトを渡します。
関数コンポーネントからクラスに変更した理由と、node => { this.inputElement = node}
に変更した理由はこちらの記事を参照してください。
refの使用
inputRef
の使用については、
React公式ページの例がわかりやすいと思います。
Callback Refs
You can pass callback refs between components like you can with object refs that were created with React.createRef().
function CustomTextInput(props) { return ( <div> <input ref={props.inputRef} /> </div> ); } class Parent extends React.Component { render() { return ( <CustomTextInput inputRef={el => this.inputElement = el} /> ); } }
In the example above, Parent passes its ref callback as an inputRef prop to the CustomTextInput, and the CustomTextInput passes the same function as a special ref attribute to the <input>. As a result, this.inputElement in Parent will be set to the DOM node corresponding to the <input> element in the CustomTextInput.
"React.createdRef()でrefを作成したのと同じように、コンポーネント間でコールバックrefを渡すことができます。
上記の例では、親コンポーネントはCustomTextInputにrefコールバックをinputRefプロパティとして渡し、CustomTextInputはinputRefで受け取った関数を<input>のref属性に設定しています。そのため、親コンポーネントのthis.inputElementはCustomTextInputの<input>のDOMノードが設定されることになります。"
あとがき
refが何であるかきちんと理解しないままinputをTextFieldに置き換えていたので、ハマりました。公式ドキュメント(Refs and the DOM – React) を読んでrefの理解が深まりました。
バージョン
- @material-ui/core: 3.4.0