Material-UIでrefを使う
メモ。
以下のようなコンポーネントの <input type="text"> 項目を Material-UI の TextField に置き換えようと思ったが
ref で参照しているのをそのまま TextField でも使えるのか迷った。
import React, { PropTypes } from 'react'; export default class AddTodoForm extends React.Component { handleSubmit(e) { e.preventDefault(); const node = this.refs.input; const text = node.value.trim(); if (!text) { return; } this.props.onSubmit(text); node.value = ''; } render() { return ( <div> <form onSubmit={(e) => this.handleSubmit(e)}> <input type="text" ref="input" /> <button type="submit"> Add Todo </button> </form> </div> ); } } AddTodoForm.propTypes = { onSubmit: PropTypes.func.isRequired, };
先に結論
値の参照だけしたいときは
this.refs.xxx.getValue()
とし、DOM Node を取得する場合は
this.refs.xxx.getInputNode()
を使う。
両方ともドキュメントには載っておらず、前者は以下の Stack Overflow から
javascript - How get data from material-ui TextField, DropDownMenu components? - Stack Overflow
後者は以下のようにブラウザの開発者コンソールから無理やり見つけた。

string ref を使う場合
import React, { PropTypes } from 'react';
+import RaisedButton from 'material-ui/RaisedButton';
+import TextField from 'material-ui/TextField';
export default class AddTodoForm extends React.Component {
handleSubmit(e) {
e.preventDefault();
- const node = this.refs.input;
+ const node = this.refs.input.getInputNode();
const text = node.value.trim();
if (!text) {
return;
@@ -16,10 +18,8 @@ export default class AddTodoForm extends React.Component {
return (
<div>
<form onSubmit={(e) => this.handleSubmit(e)}>
- <input ref="input" />
- <button type="submit">
- Add Todo
- </button>
+ <TextField id="todo-title" ref="input" />
+ <RaisedButton label="Add Todo" onTouchTap={(e) => this.handleSubmit(e)} />
</form>
</div>
);
diff --git a/src/containers/App.js b/src/containers/App.js
index 8068f95..4ee5acf 100644
--- a/src/containers/App.js
+++ b/src/containers/App.js
@@ -18,4 +18,3 @@ export default class App extends React.Component {
);
}
}
arrow function による ref を使う場合
上述した string ref は現在推奨されていないらしい
(参考:http://reactjs.cn/react/docs/more-about-refs.html#the-ref-string-attribute)
ので、arrow 関数を使った場合の書き方も載せておく。
https://facebook.github.io/react/docs/refs-and-the-dom.html
import React, { PropTypes } from 'react';
+import RaisedButton from 'material-ui/RaisedButton';
+import TextField from 'material-ui/TextField';
export default class AddTodoForm extends React.Component {
handleSubmit(e) {
e.preventDefault();
- const node = this.refs.input;
+ const node = this.input.getInputNode();
const text = node.value.trim();
if (!text) {
return;
@@ -16,10 +18,8 @@ export default class AddTodoForm extends React.Component {
return (
<div>
<form onSubmit={(e) => this.handleSubmit(e)}>
- <input ref="input" />
- <button type="submit">
- Add Todo
- </button>
+ <TextField id="todo-title" ref={(input) => this.input = input} />
+ <RaisedButton label="Add Todo" onTouchTap={(e) => this.handleSubmit(e)} />
</form>
</div>
);
);
}
}