10年を振り返る

先日30歳の誕生日を迎え、今日は仕事納めです。思考の変遷を振り返ってみたい気持ちになりました。

20歳頃

まだ高校生だった気がします。その後ニートとフリーターを行ったり来たりで。

狂ったようにカラオケに行ったり、原付でツーリングに行ったりしても、「本当はこんなことやってる場合じゃない」という苦しい気持ちが常にありました。このままでは自分はダメなんだ、明日は正しいことをするんだ、と毎日思うものの、秋田の凍りつくような寒さと、時給600円の激安スーパー店レジバイトの前ではなんの役にも立たない決心でした。

弟が大学に落ちて予備校に行くというので、なんとか自分を変えようと思い同じ予備校へ入り、高校生に混じって勉強しました。

会津大学という超コスパのいいコンピュータ専門の単科大学があり、割と簡単かつ受験科目が少ないというので運よく潜り込めました。

23歳〜

もともと計算機と Linux が好きだったので1年目はチートできました。ただ、勉強習慣が無かったので数学系はどうやって単位を取ったのか覚えていないくらい身につきませんでした。さらに睡眠の習慣すら無かったので、人間関係とかソフトスキル的なものは破滅していたと思います。

この頃考えていたのは就職のことです。ワープワ脳なので3年目くらいまで本気で正規雇用をゴールにしていました。今思うと本当に低いハードル設定だと思うんですが、当時は東北近辺で中小企業に入れれば最高だな😸 と思っていました。

ただ、大学というのは自分にとっては蜘蛛の糸です。せっかくのチャンスだから会津大学でできることには全部関わろうと思いいろんなイベントに参加して活動しました。ハッカソンとか勉強会とか。あと大学周辺ベンチャーの Eyes, JAPAN という会社でバイトをして大変お世話になりました。その辺りで出会った人々から、コンピュータエンジニアとしての習慣を吸収しました。

就職時の年齢を気にしていたので飛び級制度を使い、学部3年+院2年で卒業することに決め、指導教員の先生のご指導のおかげでなんとか大学院に進めました。

26歳〜

コンピュータの動作原理を知っておきたかったので、奥山先生の研究室で回路設計を勉強しました。ただ、どういう技術トピックで他者と差別化するのかという考えばかりが強く、寄り道に多くの時間を使ってしまいました。

この頃考えていたのは「コンピュータエンジニアとして」どうするのか、という縛りでした。今思えば囚われ過ぎでしたが、ゴールも変わりました。就職を考える上でエンジニアとして社会とどう付き合っていくのかいうことです。

そこでエンジニアの働きは社会貢献に尽きるという信条を見出し、それを軸に仕事を探しました。新卒求人を始めたばかりのクラウドの会社があり、考え方が非常にマッチしていたので運よく拾っていただきました。

なんとか働いています。

社会人1年目は、睡眠とか勉強習慣とか、ツケにしていた問題が表面化していました。成果は出ないし体調は崩すしで、エンジニア云々以前の体のバグフィックスに時間を費やしました。

2年目になって気づいたのが、学生の時に必死になっていた技術的な知識の役の立たなさです。エンジニアの仕事は知識を持つことではなくて、問題を解決することです。これは技術の分野はあまり関係ないなと思いました。したがって、今はある程度専門性はあるものの固有の技術について固執していません。また、大学の頃のように、誰かの課題を解決できているわけではないのに表面的な雰囲気(githubとかね)を作ろうとするのはきっぱり辞めました。

そして昔と違って、これからどうなりたいのかはあまり思いつきません... まずはちゃんと人の役に立ちたいです。


そもそもなんでこの記事書いてるんでしょうね。とりあえず、自分の20歳の頃と似たような若者が居たら励ましたいです。こういう人の空白期間ってマジで空白ですからね。海外でバックパッカーとかしてたりしないですし。

振り返ってみると大きなステップを超えていくたびに考えていることがどんどん洗練されていくもんだなと感じます。20歳の自分のまま同じことを繰り返して歳を取っても、こうはならないと思います。

.styをTeX Liveに入れる方法(root不要)

ユーザ権限で行いたい。

この場合、~/texmfに置いておけば自動的に毎回読んでくれるらしい。

TeX Live - ArchWiki

たとえば CTAN: Package bytefield これを入れるときは、

$ mkdir ~/texmf
$ unzip bytefield.zip
(幸いこの中にはコンパイル済みの.styが入っていた)
$ cp -r tex/ ~/texmf
$ tree ~/texmf
/home/ishikuro/texmf/
└── tex
    └── latex
        └── bytefield
            └── bytefield.sty
(使えるかどうか確認)
$ kpsewhich bytefield.sty
/home/ishikuro/texmf/tex/latex/bytefield/bytefield.sty

あとはドキュメントに従って\usepackageなりするとよい。

pngとかjpgをplatexで使う(debian jessie)

注意: この方法でpngを貼ると、PostScriptプリンタでの印刷でとても時間がかかるようになる。パワポで作った図表はできればpdfで出力して貼り込むのがよいと思う。

$ sudo apt install texlive-lang-japanese latexmk

~/.latexmk

#!/usr/bin/perl
$latex         = 'platex %O %S';
$bibtex        = 'pbibtex %O %B';
$dvipdf        = 'dvipdfmx %O %S';
$pdf_mode      = 3; # use dvipdf
$pdf_previewer = "evince"

files:

main.tex
figure/
    a.png
    b.png

main.tex

...
\usepackage[dvipdfmx][graphicx]
\graphicspath{{./figure/}}
...


\begin{figure}
  \includegraphics{a.png}
\end

このままだとエラーになる

$ latexmk main.tex

runpopen command not allowed: extractbb

extractbbの許可

$ sudo cp /usr/share/texlive/texmf.cnf /etc/texmf/texmf.d/90extractbb.cnf

90extractbb.cnfにextractbbを追加

shell_escape_commands = extractbb,bibtex,bibtex8,kpsewhich,makeindex,mpost,repstopdf,
$ sudo update-texmf
$ latexmk main.tex

これで画像が自動で挿入される。いまどきはepsとか用意しなくていい。

WebからFPGAの回路を記述できる簡易IDEを作った

これはAizu Advent Calender 2015の21日目の記事です。
前は@yutoppさんです
次は@about_hiroppyさんの予定です。

はじめに

会津大学の学生のishikuroです。こんにちは。

需要がありそうだったので(確信)、育毛のプレゼンを書くつもりでしたが、今日12月21日は私の0x1C回目の誕生日であり、この先の一年の悪い暗示になってしまいそうなのと、優先的に紹介しないといけないものを思い出したのでやめます。育毛について聞きたい方は直接ご連絡ください。ちなみに誕生日についてはささやかなアピールです。

今日は「WebからFPGAの回路を記述できる簡易IDE」をyattan氏をはじめとした研究室のメンバーと一緒に作った経緯をお話しようと思います。

f:id:ishn:20151221174158g:plain


youtu.be

Webインターフェイスから回路を記述し、サーバーに接続されたFPGAボードに書き込みができます。

経緯

私の研究室では毎年グループワークの訓練も兼ねて、研究とは別に組み込みっぽい工作をしており、オープンキャンパスの日に研究成果と一緒に展示しています。

f:id:ishn:20151221162012p:plain
画像の出典: 研究室のpublicなサイト

今年の私の班は「高校生向けにコンピュータハードウェアの設計体験ワークショップを開く」というのに挑戦しました。私含め院2年生2名, 学部3年生4人で実行。



画像の下の方に見えてる工作も、ものすごいプロジェクトではあるんですが今回はチラ見せだけです。

このワークショップのオマケとして、ハードウェア記述言語のことも知ってもらえるかもしれないと思って作っていたものがあります。それが、ハードウェア記述言語のコンパイラおよびFPGA書き込みツールの、簡易IDEです。Arduino, ProcessingのIDEからインスパイアを受けてます。教育用として作りましたが、これが応用次第で「リモートからFPGAの回路を記述できるシステム」になるんです。

ishikuro/asolide · GitHub

githubに反映されてない部分もありますが、班内で分担して学部生も平等にコードを書きました。

ワークショップ当日は、来場者に論理ゲートの工作で4bit adderを作ってもらい動作を確認してもらいます。その後、工作と同じ内容のハードウェア記述を本IDEで実演し、同様な動作をすることを見てもらうつもりでした。しかし、演習内容を吟味した結果、来場者にとって詰め込みすぎになって疲れてしまうんではないかということが分かってきました。結局このシステムは当日は展示だけに留まっています。

機能

できること

NSLで回路を記述できる

世界で初めてハードウェア記述言語を提案したのは実は日本のNTT研究所でした。それまでは模造紙に論理を描いていたそうです。

今回のシステムでは国産ハードウェア記述言語の末裔、NSLを使っています。業界標準のVerilogHDLよりも抽象的に書けるのが利点です。

ちなみに今回のシステムに似たアイディアとして、NSLのオンラインコンパイラがあります。
NSL CORE TRIAL USE

このハードウェア記述言語で、GPIOの動作を記述していくことになります。

書き込みボタン以外なにもついてない

Altera等のFPGAメーカが提供するIDEEclipseよりも巨大で、周辺ツールが膨大になっています。しかし、そこから回路の論理設計のエッセンスだけを抽出したいと思い、ArduinoやProcessingのIDEのようなものを提案しました。書き込みボタンを押すと、回路設計のための様々なステップを隠蔽して、FPGAに書き込みをします。

FPGAではGPIOを制御

GPGPUのようなアクセラレータとしてFPGAを使う場合はPCIeとかに接続するのですが、今回はGPIOの操作だけを行えます。オンラインのArduinoみたいな感じです。

仕組み

Node.jsがメインのフレームワークです。

フロントエンド

入力したソースをサーバー側にPOSTして、コンパイルのログをsocket.ioで受け取ります。

複数ウィンドウを開いた状態で書き込みボタンを押すと、古いほうを中断してくれます。

バックエンド

以下のフローを子プロセスで実行します。

逐一、ログをフロントエンド側にsocket.ioで送ります。

FPGAの書き込みが終わったら、GPIOと記述した回路の動作が始まります。

未実装

今後の展望

XeonFPGAが載るなんて夢のある話もありますよね。きっと将来、AWS上でFPGAアクセラレーションがかけられるインスタンスも登場するんじゃないかと予想しています。

今回作ったやつは、書き込みこそUSB Blasterですが、実行時のFPGAとのインターフェイスはGPIOしかありません。サーバーとFPGAボードをPCIeと接続して、FPGAのリソーススケジューラみたいなのを実装すれば、もしかしたらクラウドFPGAの簡易的な実現と言えるかもしれません。

また、現在の構成だけでも、ArduinoのようなIoT的な使い方はできそうです。

余談ですが、いつかgithubのような場で回路関連のツールがどんどん出てくる時代になってほしいです。gemとかnpmみたいなコミュニティベースのエコシステムは一切ありえない回路設計業界ですが、オープンソースハードウェアの潮流がこちらに目を向けてくれたらと思ってます。

termdownでポモドーロテクニック

30分とか短時間で集中して作業するのが効果的らしい。まわりの人も結構やってたので私もやっている。termdownというツールが良かったので備忘録として書く。

ポモドーロテクニックとは - はてなキーワード

アジャイルな時間管理術 ポモドーロテクニック入門 | Staffan Noeteberg, 渋川 よしき, 渋川 あき | 本 | Amazon.co.jp

集中して仕事をこなすために、25分毎に時間を区切って仕事をする時間管理術。Francesco Cirillo氏が1992年、自身の勉強効率を上げるために考案した。

手順

1. 25分を1ポモドーロとし、やるべきタスクを1ポモドーロ刻み(25分毎)に分ける。
2. 25分間は、他の事は一切やらず、タスクに集中する
3. 25分経てば、5分間の休憩を入れる
4. 4ポモドーロ毎(2時間毎)に30分程の長い休憩をとる
5. 後は上記を繰り返す

ただし、いまいち良いアプリが無い。

欲しいキッチンタイマーアプリ:

  • 環境非依存
  • 変なイラストとかが入らない

探してみたところ、termdownというコマンドが要件を満たしていた。

インストール

python製であり、pipでインストールできる

sudo pip install termdown

使い方

termdown -a -b -c 10 --no-figlet 25m
  • -a, --alt-format: 付けないと、"24m 28s"みたいな表記になる
  • -b, --bliknk: 終了時目立つようにする
  • -c, --critical N: 最後のN秒を赤字にする
  • --no-figlet: デフォルトだとアスキーアートで表示されるのだが、場所をとるので表示しないようにできる

ターミナルのウィンドウを専有させて、文字サイズを大きめにし、Always on Topしておくと便利。

f:id:ishn:20151118104220p:plain

関連記事

ishikuro.hateblo.jp

React + TypeScript + Webpackの最小構成

このエントリは古い情報です。

今は typescript の代わりに flowtype も使えそうです。また、ブートストラップとしては create-react-app が提供されており、ここからカスタマイズしたほうが便利だと思います。

github.com


前回

ishikuro.hateblo.jp

の続き。前回のリポジトリを元にTypeScript版を作ってみたい:

GitHub - ishikuro/thinking-in-react-webpack-minimum at typescript

最終的なファイルツリー

.
├── dist
│   ├── bundle.js
│   └── index.html
├── package.json
├── README.md
├── src
│   ├── app.tsx
│   ├── tsd.json
│   └── typings
│       ├── react
│       │   └── react.d.ts
│       └── tsd.d.ts
├── tsconfig.json
└── webpack.config.js

今回もサーバーは立ち上げずにブラウザで直接ローカルのindex.htmlファイルを開いて動作を確認する。

前回と比較すると、型定義ファイル(typings/)とコンパイルオプション(tsconfig.json)が追加されている。

TypeScriptで記述

webpack中やvimプラグインで使われるので先にtypescriptのnpmを入れておく。

npm install -g typescript

.vimrc

" syntax highlightを有効にする
NeoBundle 'leafgarland/typescript-vim'
" typescriptのインデントを適切にする
NeoBundle 'jason0x43/vim-js-indent'
" コード補完や定義/参照へのジャンプをできるようにする
NeoBundle 'Quramy/tsuquyomi'
" .tsxもtypescriptとして扱う
autocmd BufNewFile,BufRead *.{ts,tsx} set filetype=typescript

型定義ファイルを追加

npm install -g tsd
cd src/
tsd query react --action install --resolve --save

コンパイル方法

TypeScript内でJSXやReactを扱うために、様々なハックが存在していたが、2015年7月ころにtypescriptがJSXをネイティブサポートしたために収束した。

  • typescript 1.6以上でコンパイルすればok, webpackで使う場合はnpm install --save-dev typescript@nextで入れる
  • 拡張子は.tsxにしておく
  • webpackでの利用方法や、Reactのコーディング方法はts-loaderのtestで提示されている。

babelの代わりにts-loaderを使う

npm install --save-dev typescript@next ts-loader

tsconfig.jsonを作成。(コンパイラオプションやリンカ的なものを指示するファイル)

{
  "compilerOptions": {
    "jsx": "react"
  },
  "files": [
    "src/typings/tsd.d.ts"
  ]
}

webpack.config.jsを更新。拡張子をtsxにして、ts-loaderを使うようにするだけ。(Option: コンパイル速度を上げるためにはexternal指定でreactをビルドに含めないようにする。html側で読み込む。参考: ReactとStylusをwebpackで使うための開発環境構築)

module.exports = {
  entry: [
    './src/app.tsx'
  ],
  output: {
    path: 'dist',
    filename: 'bundle.js'
  },
  resolve: {
    extensions: ['', '.tsx', '.ts', '.js']
  },
  externals: {
    react: 'React'
  },
  module: {
    loaders: [
      { test: /\.ts(x?)$/, loader: 'ts-loader' }
    ]
  }
};

(Option: dist/index.html reactを別ファイルで読み込む。)

<!DOCTYPE html>
<html>
  <head>
    <title>Thinking in React</title>
  </head>
  <body>
    <script src="../node_modules/react/dist/react-with-addons.min.js"></script>
    <script src="bundle.js"></script>
  </body>
</html>

src/app.tsxのサンプル。ポイントは、propsなどの受け渡しをinterfaceで行うこと。これだけでもだいぶ人に伝えやすくなると思った。

/// <reference path="typings/tsd.d.ts" />
import * as React from 'react';

interface Props {
  content: string;
}

class MyComponent extends React.Component<Props, {}> {
  render() {
    return <div>{this.props.content}</div>
  }
}

React.render(<MyComponent content="Hello World" />, document.body);

あとはコンパイルして確認

webpack
open dist/index.html

追記: ソースコードの変更点

全文はこちら: thinking-in-react-webpack-minimum/app.tsx at typescript · ishikuro/thinking-in-react-webpack-minimum · GitHub

import

/// <reference path="typings/tsd.d.ts" />
import * as React from 'react';

基本

interface PCRProps {
  category: string;
  key: string;
}

class ProductCategoryRow extends React.Component<PCRProps, {}> {
  render() {
    return (<tr><th colSpan={2}>{this.props.category}</th></tr>);
  }
}
  • propsやstateはinterfaceを作って明示する。extends React.Component<P, S>の形式でclassを作る。
  • JSXのプロパティも型があって、<th colSpan="2">もエラーになったので{2}としている。

ハマったところ

class SearchBar extends React.Component<SBProps, {}> {
  handleChange() {
    this.props.onUserInput(
        React.findDOMNode(this.refs.filterTextInput).value,
        React.findDOMNode(this.refs.inStockOnlyInput).checked
    );
  }

  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Search..."
          value={this.props.filterText}
          ref={"filterTextInput"}
          onChange={this.handleChange.bind(this)}
        />
        <p>
          <input
            type="checkbox"
            checked={this.props.inStockOnly}
            ref="inStockOnlyInput"
            onChange={this.handleChange.bind(this)}
          />
          {' '}
          Only show products in stock
        </p>
      </form>
    );
  }
}
  • React 0.13からDOMNodeの取得方法が変更になっている (React v0.13 - React Blog)
  • extends React.Componentから作る場合は、onChange={this.handleChange.bind(this)}のようにコールバックに.bindを自分で付けないとだめ

this.refsはランタイムで設定されるんだけど、TypeScriptコンパイラは分かってくれてないのでエラーを出す。

ERROR in ./src/app.tsx
(98,37): error TS2339: Property 'filterTextInput' does not exist on type '{ [key: strin
g]: Component<any, any>; }'.

ERROR in ./src/app.tsx
(98,54): error TS2339: Property 'value' does not exist on type 'Element'.

ERROR in ./src/app.tsx
(99,37): error TS2339: Property 'inStockOnlyInput' does not exist on type '{ [key: stri
ng]: Component<any, any>; }'.

ERROR in ./src/app.tsx
(99,55): error TS2339: Property 'checked' does not exist on type 'Element'.

解決方法は不明。一応、エラーを出しつつも.jsファイルは作ってくれて、意図した動作もするんだけど、とても嫌な感じ。

this.refsは使わないように、handleChange(e)から、e.target.valueみたいに取得する方針にして回避する。

Stateの初期化

interface FPTState {
  filterText: string;
  inStockOnly: boolean;
}

class FilterableProductTable extends React.Component<FPTProps, FPTState> {
  constructor(props) {
    super(props);
    this.state = {
      filterText: '',
      inStockOnly: false
    };
  }
...
  • getInitialStateはES6的な記述では使えない。代わりにconstructorを使う

JSONとかJSオブジェクトの読み込み

var PRODUCTS = [
  {category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football'},
  {category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball'},
  {category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball'},
  {category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch'},
  {category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5'},
  {category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7'}
];

interface Product {
  category: string;
  price: string;
  stocked: boolean;
  name: string;
}

interface FPTProps {
  products: Product[];
}

React.render(<FilterableProductTable products={PRODUCTS} />, document.body);
  • そのままだとPropsに流し込めないので、一旦interfaceでラップする。

Reactのチュートリアルをやってみた

完全に自分用メモ。

Thinking in Reactというチュートリアルを最小webpack構成で試した:

ishikuro/thinking-in-react-webpack-minimum · GitHub

React + Fluxの自分メモ

Webフロントエンドのプログラミングは、jQueryによる素朴なDOM操作から、AngularJSのような双方向バインディングへ移行してきた。しかしWebがコンポーネント指向に進むに従って、状態の管理が分散しがちであることが問題であった。

そこでFacebookが新世代のパラダイムを提案している。コンポーネント指向、仮想DOM、単方向バインディングなViewライブラリのReactを開発し、Fluxという単方向データフローのアーキテクチャを推奨した。

Fluxはアーキテクチャの名前であり、実装に規定はない。従ってgithubでもFluxアーキテクチャの実装が乱立している。今回はReactと、Flux亜種のひとつであるReduxという組み合わせを、Webpackを使って学習した。

これまで、自分でもAngularJS世代(双方向バインディング世代)のVue.jsで開発をしてきたが、きちんとしたデータフローを作ろうとすると自然とFluxっぽい設計になっていた。最上位VueコンポーネントをRootとして、状態はRootへ集約して、子コンポーネントが拾うユーザアクションは全てRootに伝える。Rootにビジネスロジックを持たせて、そこでデータを編集した状態を子コンポーネントに伝播させていってたりとか。Fluxはそういう手法を明確にレールにした印象。

React

Tutorial

Thinking in React

ファイル構成

webpack.config.js: src/*.jsをコンパイルして, dist/bundle.jsへ配置
dist/
  + index.html: bundle.jsをロードするだけ
src/
  + app.js: reactのimportと、実コードを書く

webpack.config.js

module.exports = {
  entry: [
    './src/app'
  ],
  output: {
    path: 'dist',
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loader: 'babel'
    }]
  }
};

dist/index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Thinking in React</title>
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

コンパイル方法

$ npm install -g webpack
$ npm install --save-dev babel-loader
$ npm install --save react
$ webpack
$ open dist/index.html

以下はThinking in Reactより。箇条書きは意訳でもなく、読書メモ的なもの。

Step 1: UIをコンポーネントに分割して名前をつける

  • UI要素を箱で囲っていって、名前をつけていく。それがコンポーネントになる。
  • "single responsibility principle" 1つのコンポーネントには1つの責務だけを負わせる。
  • information architectureに注意。JSONのデータモデルと視覚化されたUIがうまく一致するのが良い構造だ。

  • FilterableProductTable

    • SearchgBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow
      • ProductRow
      • ...
      • ProductCategoryRow
      • ProductRow
      • ProductRow
      • ...

Step 2: Reactで静的なバージョンを作ってみる

  • まずはインタラクションが無いバージョンを作ってみる。タイプ量が膨大だが考えることは少ない。
  • データモデルを描画を意識する。親コンポーネントから子コンポーネントへのデータフローにはpropsを使う。stateは現段階では使ってはいけない。それが必要になるのはインタラクションを追加するときだけだ。
  • 書くときはトップダウンでもボトムアップでも良い。小さいサンプルではトップダウンが楽だ。大きいプロジェクトではボトムアップにしてテストを書く。
  • このステップで作ったコードは、データモデルをあらわすコンポーネントライブラリになる。

Step2のコードを入れて、コンパイルしてみる。

Reactはwebpackを使ってbundleしてやるので、

import React from 'react';

を一番上に付け加える。

Step 3: 最小のUI stateを特定する

  • インタラクティブにするために、Reactではstateを使ってデータモデルへ変更を伝える。
  • DRYに沿って作る。最小のmutable stateを特定する。(富豪的に考える。キャッシュはひとまず考えない)
    1. 親か流れてくるpropsはstateにはしない
    2. 時間で変化しないものはstateにしない
    3. 他のpropsやstateから計算できるものはstateにしない

次のデータ一覧のうち*印をつけたものが今回のstate

Step 4: stateがどこに伝播するのか決める

ProductTableはSearchBarのフィルターを使う。ここでまとめるようなコンポーネントはFilterableProductTableである。よってフィルターテキストやチェックボックスのstateはFilterableProductTableに持たせる。子コンポーネントにはpropsを使って渡す。

Step 5: 子から親へのデータフローの追加

  • SearchBarからFilterableProductTableへ変更を伝えるコードを追加する。
  • Reactの方法では2wayバインディングよりもコード量は増えるが、明示的で分かりやすい。
  • inputタグのvalueは常に親からのpropsを反映している。
  • inputタグのvalueに変更があれば、SearchBarのhandleChange()が呼ばれ、その中で、prop.onUserInputというコールバックが呼ばれている。(propsにはコールバックを指定することもできる。)
  • このコールバックは親のFilterableProductTableのstateを変更するものである。 f:id:ishn:20150831145951p:plain

Flux(Redux)は次回。