saitoxu.io

AboutTwitterGitHub

ReactでTODOアプリ

March 30, 2017

これまで何度か React を触ってきましたが、 今回はこれまでの復習がてら、ありがちですが TODO アプリを作ってみます。

今回の完成形はこんな感じ ↓

todo-app

1. 設計図を描く

最初にコンポーネントの構成を考えます。

今回はこんな感じでいってみます。

Components

TODO リスト全体の状態管理はAppコンポーネントでやって、 各 TODO のそれはTodoコンポーネントでやることにします。

2. 実装

実装は次のようになります。

※これ以外にエントリーポイントの JS や CSS が必要になります。

import React, { Component } from 'react';
import Form from './Form';
import TodoList from './TodoList';
export default class App extends Component {
constructor() {
super();
this.state = {
todos: []
};
}
handleSubmit(e) {
e.preventDefault();
const title = e.target.elements[0].value;
if (!title) {
return;
}
const desc = e.target.elements[1].value;
const todos = this.state.todos.slice()
todos.push({
title: title,
desc: desc,
done: false
});
this.setState({ todos: todos });
}
render() {
return (
<div>
<Form onSubmit={this.handleSubmit.bind(this)} />
<TodoList todos={this.state.todos} />
</div>
);
}
}
view raw App.js hosted with ❤ by GitHub

import React, { Component } from 'react';
export default class Form extends Component {
render() {
return (
<div>
<form onSubmit={this.props.onSubmit}>
<input type="text" placeholder="title"/><br/>
<textarea placeholder="description" rows="8"></textarea><br/>
<button type="submit">Create</button>
</form>
</div>
);
}
}
view raw Form.js hosted with ❤ by GitHub

import React, { Component } from 'react';
import Todo from './Todo';
export default class TodoList extends Component {
render() {
const todos = [];
for (let i = 0; i < this.props.todos.length; i++) {
todos.push(
<Todo
key={i}
title={this.props.todos[i].title}
desc={this.props.todos[i].desc}
done={this.props.todos[i].done}
/>
);
}
return (
<ol>
{todos}
</ol>
);
}
}
view raw TodoList.js hosted with ❤ by GitHub

import React, { Component } from 'react';
export default class Todo extends Component {
constructor(props) {
super(props);
this.state = {
title: props.title,
desc: props.desc,
done: props.done
};
}
handleClick(e) {
e.preventDefault();
this.setState({
done: !this.state.done
});
}
render() {
const link = this.state.done? 'Undone' : 'Done';
const className = this.state.done? 'done' : null;
return (
<li>
<span className={className}>{this.state.title}</span>
&nbsp;
<a href="#" onClick={this.handleClick.bind(this)}>{link}</a>
</li>
);
}
}
view raw Todo.js hosted with ❤ by GitHub

3. おわりに

以上、簡単な TODO アプリを作ってみました。

今回、せっかく用意した TODO の description フィールドを使っていないのですが、 これは次回react-routerの練習を兼ねて使う予定です。