Help us understand the problem. What is going on with this article?

【React】ToDoアプリを作ってみよう【前編】

:star: 対象

  • Reactの概念をなんとなく理解したので、実際に簡単なアプリを作ってみたい方
  • Reactの日本語チュートリアルがなくなって困っている方

:star: 関連

:star: 目標

  • Reactで画像のようなToDoアプリを作ります。
  • 今回はTodoを表示させるところまで実装してみましょう。
  • 見本:GitHub

todo-app4.gif

:star: 手順

:pencil: 環境構築

:pencil2: Reactの環境構築を最短で行う

  • package.jsonがあるディレクトリ(アプリ名のディレクトリ)でnpm startを実行することでアプリが起動します。この状態でファイルを編集&保存すると、瞬時に結果が反映されるため、非常に便利です。

:pencil2: ディレクトリ構成(例)

.
├── node_modules
├── package-lock.json
├── package.json
├── public
│   ├── data1.json
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.js
    ├── App.test.js
    ├── Form.js
    ├── Todo.js
    ├── TodoList.js
    ├── css
    │   ├── App.css
    │   ├── form.css
    │   ├── index.css
    │   └── todo.css
    ├── index.js
    └── registerServiceWorker.js

# 一部省略
  • CSSを書くのが面倒な方はこちらに見本があるので使ってください。

:pencil: Todoを表示させよう

:pencil2: index.js

src/index.js
import './css/index.css'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(<App />, document.getElementById('root'))
  • import 〇〇 from 'ファイル名など':別のファイルで指定した〇〇(クラス名や変数)を使うことができます。import React from 'react'はReactを使うファイルでは必須です。
  • ReactDOM.Render()でHTMLのidのある場所にコンポーネントを挿入します。今回は、public/index.html にある<div id="root"></div>にAppコンポーネントを挿入しています。

:pencil2: App.js

src/App.js
import React, { Component } from 'react';
import TodoList from './TodoList';
import './css/App.css'


class App extends Component {

  constructor() {
    super()
    this.state = {
      todos: [
        {
          id: 1,
          title: "Hello, React!",
          desc: "React始めました",
          done: false
        },
        {
          id: 2,
          title: "Hello, Redux!",
          desc: "Reduxも始めました",
          done: false
        },
      ]
    }
  }

  render() {
    return (
      <div className="app">
        <h1>todoアプリを作ってみた</h1>
        <TodoList
          todos={this.state.todos}
          />
      </div>
    );
  }
}

export default App


  • class 〇〇 extends Component{}でコンポーネントと呼ばれるクラスを作成します。これを組み合わせて様々なviewを作れるのがReactの特徴の一つです。
  • constructorでは初期値を設定します。super()Componentを継承するため必須です。
  • this.stateはこのクラスのstateを示しています。今回はtodosという配列に各キーとバリューを設定しておきます。
  • render(){}でHTMLとして渡したい変数などを設定し、return()の中に実際に返したいHTMLそのものを記述します。実際にHTMLに近いJSXと言う記法です。HTMLのclassはJSXではclassNameとなるので気をつけましょう。
  • 呼び出したいコンポーネントは<TodoList />のように記述します。さらに、todos={this.state.todos}のように、そのコンポーネントに渡したい内容も書いてあげましょう。これで、TodoListでtodosという変数を使えるようになりました。
  • export default 〇〇でimportされた時にデフォルトで呼び出されるものを定義します。

:pencil2: TodoList.js

src/TodoList.js
import React, { Component } from 'react';
import Todo from './Todo';


class TodoList extends Component {

  render() {
    const todos = this.props.todos.map( todo =>
      <Todo
        key={todo.id}
        {...todo}
      />
    )

    return(
      <ul>
        {todos}
      </ul>
    );
  }
}

export default TodoList
  • 親コンポーネントから渡されたものはthis.propsを使って受け取ることができます。
  • TodoListから複数のTodoができる時など、子コンポーネントに同じ形式の配列を渡す時は、それらを区別するための絶対に重複しないkeyを設定する必要があります。今回はtodo.idをkeyに入れます。
  • {...todo}はtodoに入っている要素を全て引き継ぐ、と言う意味です。
  • returnでの配列の入ったtodosを返すことで、Todoコンポーネントでpropsとして受け取ることができます。{}で変数展開ができます。

:pencil2: Todo.js

src/Todo.js
import React, { Component } from 'react';
import './css/todo.css';

class Todo extends Component {

  render() {
    const className = 'undone'
    const link = this.props.done ? '元に戻す' : '完了!'
    return(
      <li className={className}>
        <span>{this.props.id}</span>
        <span>{this.props.title}  </span>
        <a href="">{link}</a>
        <p>{this.props.desc}</p>
      </li>
    );
  }

}

export default Todo
  • const linkは三項演算子を使って定義しています。this.props.doneがtrue(完了済)の時は「元に戻す」ボタン、false(未完了)の時は「完了」ボタンを表示するようにします。
  • returnの中でHTMLとして表示したい用要素を組み立てて完成です。

スクリーンショット 2017-07-14 14.24.34.png

:star2: 今回はここまで!

  • 内容に不備等ありましたら、お手数ですがコメントにてお願いします。

:star: 参考

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away