UIがかっこいいとコーディングもノッてくるというもの。ということでMATERIAL-UIを入れてみる。
上記を参考にする。
インストール
まずは、必要なパッケージのインストール
$ npm install @material-ui/core
マイグレーション
次に、既存のコンポーネントをMaterial-UI に変更する。
button
をButton
にul
を `List‘ にli
をListItem
&ListItemText
に
それぞれ変更していく。
ただ、そのまま実行すると onClick
の型違いでエラーが発生するので、エラーの通り修正する。
- HTMLLIElement を HTMLDivElement に変更
- React.FormEvent を React.ChangeEvent に変更
それでもまだ問題があって、li
を ListItem
と ListItemText
に分けたことで key
関係のエラーが再発する
key
属性は ListItem に記述して、id
属性は ListItemText に記述するとよい。
削除ボタンの変更
TODO
を削除するボタンは今まで普通のボタンに -
といった味気ないものだったので、これを機にゴミ箱アイコンに変更する。
List React component - Material-UI
ここらへんに良いサンプルがあるので参考にする。
新たにパッケージをインストールする。
$ npm install @material-ui/icons
以下のようにコードを変更する。これを button
と置き換えるだけだ。簡単。
... <ListItemSecondaryAction> <IconButton aria-label="Delete" onClick={this.on_click_for_del} id={String(i)}> <DeleteIcon /> </IconButton> </ListItemSecondaryAction>
マージンの設定
ここまでの実装で実行してみると、TODO追加ボタンとテキスト部分が近く感じる。いい感じにマージンを埋め込みたい。
Button React component - Material-UI
ここらへんのコードサンプルをみてみると、theme.spacing.unit
という値を margin
につけてやればいいようだが styles
を作成するのに手間取った。
Material-UI のガイド > TypeScriptを試す1 - Qiita
この記事を見ると、コンポーネントを丸っとスタイル設定用の関数でくるんでやる必要があるようだった。今回は独自のprops インターフェースは必要なかったので、以下のように定義した。
ちなみに、以下のパッケージが必要になる。
$ npm install @material-ui/styles
// スタイル設定用の関数を定義 const decorate = withStyles((theme: Theme) => { return createStyles({ button: { margin: theme.spacing.unit } }); }); // 定義部分を変更 decorate() 関数でクラスを丸っとラップ const NumberList = decorate( class extends React.Component<WithStyles<'button'>, TodoState> { // ... render() { const { classes } = this.props return ( <div className="App"> <div> // className に button 属性を指定することで、marginが効くようになる <Button color="primary" variant="contained" onClick={this.on_click} className={classes.button}>+</Button> // ...
複数のコンポーネントのスタイルを設定する
上記の設定だと button
のみが有効になる、root
の要素に関してもスタイルを設定したい場合は、WithStyles<'button'>
の部分を変更する必要がある。そのために、decorate関数で使っている withStyles をクラス定義のほうに移してくる必要がある。
// スタイル属性を定義。decorate関数にはしない。 const styles = (theme: Theme) => createStyles({ root: { width: '100%', maxWidth: 360, backgroundColor: theme.palette.background.paper, }, button: { margin: theme.spacing.unit } }); // ラップする側でwithStyles()をすることで、WithStylesにstylesのタイプを指定できるようになる const NumberList = withStyles(styles)( class extends React.Component<WithStyles<typeof styles>, TodoState> {
成果物
上記をすべて実装した場合、以下のようになる。
コード群は以下に挙げているので、興味があればみてほしい。
GitHub - bamchoh/react-study at 2019-01-28_add_material_ui
おわり。