Skip to content

Instantly share code, notes, and snippets.

@LightSpeedC
Last active November 27, 2016 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LightSpeedC/68883b6b9147f80737bd96ce64c55659 to your computer and use it in GitHub Desktop.
Save LightSpeedC/68883b6b9147f80737bd96ce64c55659 to your computer and use it in GitHub Desktop.
React v15をやってみよう (1) - まずはHTMLだけで ref: http://qiita.com/LightSpeedC/items/484fec44a2ca15e48f49
$ node -v
v6.x.x
$ npm -v
v3.x.x
$ mkdir react-lesson1
$ cd react-lesson1
$ npm init -y
$ npm i -D react react-dom
Hello Legacy React ES5! ‎12‎:34‎:56
Hello Legacy React ES6! 12:34:56
$ npm i -D babel-core@5
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<div id="container"></div>
<script>
var Hello = React.createClass({
render: function () {
return React.createElement('div', null,
'Hello Legacy React ES5! ',
new Date().toLocaleTimeString());
}
});
ReactDOM.render(React.createElement(Hello), container);
// ReactDOM.render(React.createElement(Hello),
// document.getElementById('container'));
setInterval(function () {
ReactDOM.render(React.createElement(Hello), container);
}, 1000);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<div id="container"></div>
<script>
class Hello extends React.Component {
render() {
return React.createElement('div', null,
'Hello Legacy React ES6! ',
new Date().toLocaleTimeString());
}
}
ReactDOM.render(React.createElement(Hello), container);
// ReactDOM.render(React.createElement(Hello),
// document.getElementById('container'));
setInterval(() =>
ReactDOM.render(React.createElement(Hello), container),
1000);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.38/browser.min.js"></script>-->
<div id="container"></div>
<script type="text/babel">
//<script>
class Hello extends React.Component {
render() {
return <div>
Hello Legacy React JSX!
{' ' + new Date().toLocaleTimeString()}
</div>;
}
}
ReactDOM.render(<Hello/>, container);
// ReactDOM.render(<Hello/>,
// document.getElementById('container'));
setInterval(() =>
ReactDOM.render(<Hello/>, container),
1000);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<div id="container"></div>
<script type="text/babel">
//<script>
class Hello extends React.Component {
render() {
return <div>
Hello {this.props.name}
</div>;
}
}
ReactDOM.render(<Hello name="React!"/>, container);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<div id="container"></div>
<script type="text/babel">
//<script>
const Hello = props =>
<div>
Hello {props.name}
</div>;
ReactDOM.render(<Hello name="React!"/>, container);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<div id="container"></div>
<script type="text/babel">
//<script>
// カウンター
class LegacyCounter extends React.Component {
// コンストラクタ
constructor(props, context) {
super(props, context);
this.state = {counter: 0};
this.onIncr = this.onIncr.bind(this);
}
// 増/プラス
onIncr() {
this.setState({counter: this.state.counter + 1});
}
// 減/マイナス
onDecr() {
this.setState({counter: this.state.counter - 1});
}
// レンダー
render() {
return <div>
カウンター: {this.state.counter}
<br/>
<button onClick={this.onIncr}>増</button>
<button onClick={this.onDecr.bind(this)}>減</button>
</div>;
}
}
ReactDOM.render(<LegacyCounter/>, container);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<div id="container"></div>
<script type="text/babel">
//<script>
// 私のコンポーネント (onメソッドはthisをbind)
class MyComponent extends React.Component {
// コンストラクタ
constructor(props, context) {
super(props, context);
Object.getOwnPropertyNames(this.constructor.prototype)
.forEach(x => x.substr(0, 2) === 'on' &&
typeof this[x] === 'function' &&
(this[x] = this[x].bind(this)));
}
}
// カウンター
class MyCounter extends MyComponent {
// コンストラクタ
constructor(props, context) {
super(props, context);
this.state = {counter: 0};
}
// 増/プラス
onIncr() {
this.setState(s => ({counter: s.counter + 1}));
}
// 減/マイナス
onDecr() {
this.setState(s => ({counter: s.counter - 1}));
}
// レンダー
render() {
return <div>
カウンター: {this.state.counter}
<br/>
<button children="増" onClick={this.onIncr}/>
<button children="減" onClick={this.onDecr}/>
</div>;
}
}
ReactDOM.render(<MyCounter/>, container);
</script>
<!DOCTYPE html>
<meta charset="UTF-8">
<script src="node_modules/react/dist/react.min.js"></script>
<script src="node_modules/react-dom/dist/react-dom.min.js"></script>
<script src="node_modules/babel-core/browser.min.js"></script>
<div id="container"></div>
<script type="text/babel">
//<script>
// 私のコンポーネント (onメソッドはthisをbind)
class MyComponent extends React.Component {
// コンストラクタ
constructor(props, context) {
super(props, context);
Object.getOwnPropertyNames(this.constructor.prototype)
.forEach(x => x.substr(0, 2) === 'on' &&
typeof this[x] === 'function' &&
(this[x] = this[x].bind(this)));
}
}
// タスクのクラス
class Task {
// static nextKey = 0;
// コンストラクタ
constructor(title, done) {
this._key = Task.nextKey++;
this._title = title;
this._done = !!done;
}
getKey() { return this._key; }
getTitle() { return this._title; }
isDone() { return this._done; }
toggle() { this._done = !this._done; }
}
Task.nextKey = 0;
// To Do List アプリ
class ToDoListApp extends MyComponent {
// コンストラクタ
constructor(props, context) {
super(props, context);
this.state = {title: '',
list: [new Task('最初のタスク'),
new Task('完了したタスク', true),
new Task('最後のタスク')]};
}
// 入力中のタスクのタイトルが変更された時
onChangeTitle(ev) {
this.setState({title: ev.target.value});
}
// タスクを追加する
onAddTask() {
// 入力中のタスクのタイトルがある時にタスクを追加する
this.state.title &&
this.setState(s => ({title: '',
list: s.list.concat(new Task(s.title))}));
// focus取得対応
this.elemTitle && this.elemTitle.focus();
}
// 完了済みのタスクを削除する(チェックして削除)
onRemoveCompletedTasks() {
// 未完了タスクのリストに変更する(完了済みタスクを除外する)
this.setState(s => ({list: s.list.filter(task => !task.isDone())}));
// focus取得対応
this.elemTitle && this.elemTitle.focus();
}
// 特定のタスクを削除する(Xをクリック)
removeTask(task) {
this.setState(s => ({list: s.list.filter(t => t !== task)}));
// focus取得対応
this.elemTitle && this.elemTitle.focus();
}
// タスクの完了済みと未完了をトグルする
toggleTask(task) {
task.toggle();
// focus取得対応
this.elemTitle && this.elemTitle.focus();
this.forceUpdate();
}
// タスクのスタイル(見映え)を返す
getTaskStyle(task) {
return {textDecoration: task.isDone() ? 'line-through' : 'none',
color: task.isDone() ? 'lightgray' : 'black'}
}
// レンダー
render() {
return <div>
{/* 新規タスクのタイトル入力フォーム */}
<div onKeyDown={/*Enterキー対応*/ ev => ev.keyCode !== 13 || this.onAddTask()}>
タスク: <input placeholder="タスクのタイトル" autofocus
value={this.state.title} onChange={this.onChangeTitle}
ref={/*focus取得対応*/ elem => this.elemTitle = elem}/>
<button children="追加" onClick={this.onAddTask}
disabled={!this.state.title}/> {' '}
<button children="完了済みを削除" onClick={this.onRemoveCompletedTasks}
disabled={!this.state.list.some(task => task.isDone())}/>
</div>
{/* タスクのリスト */}
{this.state.list.map(task =>
<div key={task.getKey()} onClick={() => this.toggleTask(task)}>
<span children="X" onClick={() => this.removeTask(task)}/>
<input type="checkbox" checked={task.isDone()}/>
<span children={task.getTitle()} style={this.getTaskStyle(task)}/>
</div>)}
</div>;
}
}
ReactDOM.render(<ToDoListApp/>, container);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment