React始めました〜①下準備〜
の続きです。
前回で環境構築や下準備は終わったので今回は実際に書いていきたいと思います。
HTML
まずはじめに確認用HTMLを書きます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Reactで作った「いいねボタン」のデモ (Flux不使用)</title>
</head>
<body>
<h1>Reactで作った「いいねボタン」のデモ (Flux不使用)</h1>
<div id="like-button"></div><!-- ここにコンポーネントをマウント -->
<script src="like-button.js"></script>
</body>
</html>
id=like-buttonのdiv要素に「いいねボタン」を作ります。
実際のボタンはjsファイルに書くのでここでは書きません。
そして読み込まれているlike-button.jsはコンパイル後のjsファイルなのでここではまだ出来ていません。(安心してください)
簡単に解説するとこれから作るmain.jsにボタンの部品(コンポーネント)を作っていき、コンパイルするとlike-button.jsになり、
id=like-buttonのdiv要素に「いいねボタン」が出来るという仕組みです。
JavaScript
いよいよメインディッシュになります。
と言っても、いちいち解説しながら書いてくのもめんd…参考サイトのほうが分かりやすいので
最終結果を注意点コメントと併せて書きます。
import React from "react";
import ReactDom from "react-dom";
class LikeButton extends React.Component {
constructor(props) {
super(props);
// コンポーネントにカーソルが乗ているかどうかの状態を持たせる
this.state = {
hovered: false,
count: 999, // カウント数の状態を追加
liked: false // 押したかどうかの状態を追加
}
/* イベントを付けるときは下記がないと発火しない!! */
this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this);
this.onClick = this.onClick.bind(this);
}
styles() {
return {
container: {
fontFamily: "helvetica, arial, 'hiragino kaku gothic pro', meiryo, 'ms pgothic', sans-serif",
fontSize: 11
},
like: {
display: "inline-block",
background: "#3b5998",
padding: "0px 5px",
borderRadius: 2,
color: "#ffffff",
cursor: "pointer",
float: "left",
height: 20,
lineHeight: "20px"
},
/* オブジェクトをマージしようとするとSyntaxErrorで弾かれるので二度手間だけどしょうがなく…ダレカタスケテー!! */
likeHover: {
display: "inline-block",
background: "#444",
padding: "0px 5px",
borderRadius: 2,
color: "#ffffff",
cursor: "pointer",
float: "left",
height: 20,
lineHeight: "20px"
},
counterBefore: {
display: "block",
float: "left",
width: 6,
height: 6,
background: "#fafafa",
marginLeft: "-12px",
borderRight: 10,
transform: "rotate(45deg)",
WebkitTransform: "rotate(45deg)",
marginTop: 6,
borderLeft: "1px solid #aaa",
borderBottom: "1px solid #aaa"
},
counter: {
display: "block",
background: "#fafafa",
boxSizing: "border-box",
border: "1px solid #aaa",
float: "left",
padding: "0px 8px",
borderRadius: 2,
marginLeft: 8,
height: 20,
lineHeight: "20px"
}
};
}
// カーソルが乗った時に状態を変更するイベントハンドラ
onMouseEnter() {
this.setState({hovered: true});
}
// カーソルが外れた時に状態を変更するイベントハンドラ
onMouseLeave() {
this.setState({hovered: false});
}
// クリックしたときのイベントハンドラ
onClick() {
this.setState({
count: this.state.count + (this.state.liked ? -1 : 1),
liked: !this.state.liked
});
}
render() {
const styles = this.styles();
// ↓SyntaxErrorになる(なんで?)
// const likeStyle = this.state.hovered ? {...styles.like, ...styles.likeHover} : styles.like;
const likeStyle = this.state.hovered ? styles.likeHover : styles.like;
console.log(this.state); // 状態をログに出す
/* ボタンに onMouseEnter と onMouseLeave のイベントハンドラを割り当てます
参考サイトは→onMouseEnter={::this.onMouseEnter}だけどSyntaxErrorになるので注意! */
return (
<span style={styles.container}>
<span style={likeStyle} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} onClick={this.onClick}>{this.state.liked ? "✔ " : ""}いいね!</span>
<span style={styles.counter}>
<span style={styles.counterBefore}>{" "}</span>{this.state.count}
</span>
</span>
);
}
}
ReactDom.render(
<LikeButton />,
document.getElementById("like-button")
);
これでうまく行くはずです!!絶対!!
実行
下記コマンドでdistフォルダにlike-button.jsが作成されて、確認用HTML(dist/index.html)が表示されればOKです!
npm run build
いや、まだOKじゃないか。。。
- ホバーするとボタン色が変わる
- ホバーするとコンソールにtrueが表示される
- クリックすると数が増減する
になってればOKかと思います。
終わりに
今回初めて、Reactに触れてみましたが環境構築とかいろいろ面倒くさかったので今度からは
create react appコマンドを使いたいと思います。
あと、状態管理(props、state)のとこが全然掴めてないので更にいろいろ試して勉強していきます。
その時はまた記事を書いていこうと思います。