LoginSignup
43
48

More than 5 years have passed since last update.

ReactとMaterial-UIを使ってみた

Last updated at Posted at 2016-05-10

導入

npm install

$ npm i -S react-tap-event-plugin
$ npm i -S material-ui

app.jsの初めでReact-Tap-Event-Pluginを呼ぶ

import injectTapEventPlugin from 'react-tap-event-plugin';

// Needed for onTouchTap 
// http://stackoverflow.com/a/34015469/988941 
injectTapEventPlugin();

一番親のReactComponentでthemeをセットする

import React from 'react';
import ReactDOM from 'react-dom';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import MyAwesomeReactComponent from './MyAwesomeReactComponent';

const App = () => (
  <MuiThemeProvider muiTheme={getMuiTheme()}>
    <MyAwesomeReactComponent />
  </MuiThemeProvider>
);

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

text fieldのvalueを外から操作する

text field自体のイベントならドキュメントのサンプル通りでできる

import React from 'react';
import TextField from 'material-ui/TextField';

class FormInput extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      value: 'Property Value',
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({
      value: e.target.value,
    });
  };

  render() {
    return (
      <div>
        <TextField
          hintText="message"
          value={this.state.value}
          onChange={this.handleChange}
        />
      </div>
    );
  }
}

export default FormInput;

他のコンポーネントのイベント(例えばボタン)で取る方法がわからなかった。

取得は下記で出来た

import React from 'react';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ContentAdd from 'material-ui/svg-icons/content/add';
import TextField from 'material-ui/TextField';

class FormInput extends React.Component {
  constructor(props) {
    super(props);

    this.send = this.send.bind(this);
  }

  send(e) {
    e.preventDefault();
    console.log(this.refs.myInput.getValue().trim());
  }

  render() {
    return (
      <form>
        <TextField
          hintText="message"
          ref="myInput"
          defaultValue=""
        />
        <FloatingActionButton onTouchTap={this.send}>
          <ContentAdd />
        </FloatingActionButton>
      </form>
    );
  }
}

export default FormInput;

操作

this.refs.myInput.getDOMNode().value = null;

などイロイロ試したが、下記でできた。

this.refs.myInput.input.value = null;

がなんかダサい(JQuery時代と変わらない)し、Reactっぽくない気がする。

よく考えるとメソッドの後にnullにしているということは状態を管理しているのでstateとして扱うのが正解なのかも。

state化

import React from 'react';
import FloatingActionButton from 'material-ui/FloatingActionButton';
import ContentAdd from 'material-ui/svg-icons/content/add';
import TextField from 'material-ui/TextField';

class FormInput extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      message: '',
    };

    this.send = this.send.bind(this);
    this.handleChange = this.handleChange.bind(this);
  }

  send(e) {
    e.preventDefault();
    console.log(this.state.message.trim());
    this.setState({
      message: '',
    });
  }

  handleChange(e) {
    this.setState({
      message: e.target.value,
    });
  }

  render() {
    return (
      <form>
        <TextField
          hintText="type message here"
          value={this.state.message}
          onChange={this.handleChange}
        />
        <FloatingActionButton onTouchTap={this.send}>
          <ContentAdd />
        </FloatingActionButton>
      </form>
    );
  }
}

export default FormInput;

コード量を増えましたが、どこで値が変更されているかが明示的になり、DOMを直接いじっている間もなくなりました。

参考

43
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
48