This repository has been archived by the owner on Nov 12, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Home
takanorip edited this page Aug 6, 2016
·
4 revisions
#ハンズオン概要
今回はHTMLファイルはほとんど編集しません。
react-like-button/index.html
を下記のように編集します。
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>React App</title>
</head>
<body>
<h1>Reactハンズオン</h1>
<div id="root"></div>
</body>
</html>
今回はid="root"
にコンポーネントが出力されます。
CSSはreact-like-button/src/App.css
を編集します。
今回のCSSは下記リンクにあるデザインを参考にしました。
http://stackoverflow.com/questions/23333010/how-to-draw-the-of-likes-bubble-like-what-is-on-the-right-side-of-the-facebook
.container {
font-family: helvetica, arial, 'hiragino kaku gothic pro', meiryo, 'ms pgothic', sans-serif;
font-size: 11px;
}
.like {
display: inline-block;
background: #3b5998;
padding: 0px 5px;
border-radius: 2px;
color: #ffffff;
cursor: pointer;
float: left;
height: 20px;
line-height: 20px;
}
.likeHover {
background: #444;
}
.counterBefore {
display: block;
float: left;
width: 6px;
height: 6px;
background: #fafafa;
margin-left: -12px;
border-right: 10px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
margin-top: 6px;
border-left: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
.counter {
display: block;
background: #fafafa;
box-sizing: border-box;
border: 1px solid #aaa;
float: left;
padding: 0px 8px;
border-radius: 2px;
margin-left: 8px;
height: 20px;
line-height: 20px;
}
##React
今回のメインであるReactを書いていきます。
react-like-button/src/App.js
を編集します。
まず一番外の枠を書いていきます。
最初にReactとCSSを読み込みます。import
というのはES2015で外部モジュールを読み込むときに使います。
import React, { Component } from 'react';
import './App.css';
//Componentを継承
class App extends Component {
//props, stateを記述
constructor(props) {
super(props);
}
//コンポーネントとして出力される部分
render() {
return (
<span className="container">いいねボタン</span>
);
}
}
//モジュール化
export default App;
続いて、ホバーした時の色を変えます。CSSでホバーしても良いのですが、今回はホバーしたらクラスを変化させ、色を変えたいと思います。
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
// ホバーしているかどうかの状態をstateとして保持
this.state = {
hovered: false,
}
}
// ホバー時に状態を変化させるイベントハンドラ
onMouseEnter() {
this.setState({hovered: true});
}
// カーソルが降りた時に状態を変化させるイベントハンドラ
onMouseLeave() {
this.setState({hovered: false});
}
render() {
//stateの値によってclassNameを変更
const likeClass = this.state.hovered ? "like likeHover" : "like";
console.log(this.state); // 状態をログに出す
// ボタンに onMouseEnter と onMouseLeave のイベントハンドラをbind
return (
<span className="container">
<span
onMouseEnter={this.onMouseEnter.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
className={likeClass}>いいね!</span>
<span className="counter">
<span className="counterBefore">{" "}</span>
999
</span>
</span>
);
}
}
export default App;
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hovered: false,
//状態を追加
count: 999, //カウンターの数
liked: false //クリックしたかどうか
}
}
onMouseEnter() {
this.setState({hovered: true});
}
onMouseLeave() {
this.setState({hovered: false});
}
//クリック時に状態を変化させるイベントハンドラ
onClick(){
this.setState({
//クリック時にcountの状態がfalseだったら+1、trueだったら-1
count: this.state.count + (this.state.liked ? -1 : 1),
//likedの状態を反対にする(false → true, true → false)
liked: !this.state.liked
});
}
render() {
const likeClass = this.state.hovered ? "like likeHover" : "like";
return (
<span className="container">
<span
onMouseEnter={this.onMouseEnter.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
//クリックにイベントハンドラをbind
onClick={this.onClick.bind(this)}
//likedがtrueだったら"✔"を追加
className={likeClass}>{this.state.liked ? "✔" : ""}いいね!</span>
<span className="counter">
<span className="counterBefore">{" "}</span>
//カウンターの数を表示
{this.state.count}
</span>
</span>
);
}
}
export default App;
###出力
ReactではReactDOM.render()を使ってコンポーネントを出力します。今回はindex.jsに処理が書いてあります。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; //Appモジュールを読み込み
import './index.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
##完成
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
hovered: false,
count: 999,
liked: false
}
}
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 likeClass = this.state.hovered ? "like likeHover" : "like";
return (
<span className="container">
<span
onMouseEnter={this.onMouseEnter.bind(this)}
onMouseLeave={this.onMouseLeave.bind(this)}
onClick={this.onClick.bind(this)}
className={likeClass}>{this.state.liked ? "✔" : ""}いいね!</span>
<span className="counter">
<span className="counterBefore">{" "}</span>
{this.state.count}
</span>
</span>
);
}
}
export default App;