上京エンジニアの葛藤

都会に染まる日々

react.js で keydown イベントで DOM を更新する方法

はろー。こんにちは。

react.js を最近ちょこちょこ触り始めたので、忘れんうちに書きます!

前提としてそもそもライフサイクルとか正しく理解していないし、redux ってなに???っていう状況なのですが、力技でごりごり前に進んでいきます。
書いてるうちに理解深まるやろ!!!って信じてます。

やりたいこと

「特定のキーを押下したタイミングでイベントを発火させて DOM を更新したい」

button タグを onClick で DOM を変更させるなどは、サンプルがたくさん転がっておりなんとなくでできました。
しかし単純に「→」を押下して DOM を変更させるのはどのライフサイクルで実行すればいいか悩みました。

悩んだ末の実装が以下です。

var React            = require('react');
var ReactDOM         = require('react-dom');
var createReactClass = require('create-react-class');

class SlideComponent extends React.Component {
  constructor(props, context, updater) {
    super(props, context, updater);
    this.state = { word : 'hoge' };
  }

  handleKeyDown(e) {
    if (e.keyCode == 39) {
      this.setState({word: 'foo'});
    }
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown.bind(this));
  }

  render() {
    return (
      <h1>{this.state.word}</h1>
    )
  }
}

ReactDOM.render(
  React.createElement(SlideComponent),
  document.getElementById('content')
);

ポイントは window のリサイズなどのイベントを扱いたい場合は componentDidMount() でイベントを登録して使うそうで、今回は keydown のイベントを登録しそれがトリガーで発火させるようにしました。
とても簡単ですね。

おまけ

かの有名なコナミコマンドでイベントを発火させ DOM を更新する
コナミコマンド「↑↑↓↓←→←→BA」

var React            = require('react');
var ReactDOM         = require('react-dom');
var createReactClass = require('create-react-class');

var konamiCommand = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
var input = [];  

class SlideComponent extends React.Component {
  constructor(props, context, updater) {
    super(props, context, updater);
    this.state = { word : 'hoge' };
  }

  handleKeyDown(e) {
    input.push(e.keyCode);
    if (input.toString().indexOf(konamiCommand) >= 0) {
      this.setState({word: 'KONAMI success!!!'});
      input = [];
    }
  }

  componentDidMount() {
    window.addEventListener('keydown', this.handleKeyDown.bind(this));
  }

  render() {
    return (
      <h1>{this.state.word}</h1>
    )
  }
}

ReactDOM.render(
  React.createElement(SlideComponent),
  document.getElementById('content')
);