コンポーネント間のpropsの受け渡し - React入門

React入門」、前回の「Reactで作るTODOアプリ後編」ではこれまでの総復習として簡単なTODOアプリを作成しました。今回は情報をAjaxで取得・更新が行えるように改造していきます。

今回はあくまで練習なのでAPIにはJSON Serverを利用します。

環境構築

まずは「Create React App」を利用して環境を構築していきます。

以下のコマンドでReactのインストールを行います。

create-react-app todo-app-ajax
cd todo-app-ajax
npm install
npm start

これで `http://localhost:3000` でReactアプリの表示が可能になります。

次にJSON Serverの設定を行います。
以下のコマンドでJSON Serverのインストールを行い、

npm install --save-dev json-server

db.json というファイル名で以下のようなJSONファイルを作成します。

{
  "todos": [
    {
      "id": 1,
      "title": "JavaScript覚える"
    },
    {
      "id": 2,
      "title": "jQuery覚える"
    }
  ]
}

標準では3000番ポートで立ち上がってしまうので、以下のコマンドで3001番ポートで立ち上がるように設定しています。

npx json-server --watch db.json --port 3001

App.jsは以下のように設定します。

  
import React, { Component } from 'react';
 
class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      todo: []
    };

    this.addTodo = this.addTodo.bind(this);
  }
  
  // 初期値の設定
  componentWillMount(){
    this.fetchResponse();
  }
  
  // リストの更新
  fetchResponse(){
    fetch('http://localhost:3001/todos')
    .then( res => res.json() )
    .then( res => {
      this.setState({
        todo : res
      });
    })
  }
  
  // 新規追加
  addTodo() {
    fetch('http://localhost:3001/todos', {
      method: 'POST',
      body: JSON.stringify({
        title: this.refs.newText.value
      }),
      headers: new Headers({ 'Content-type' : 'application/json' })
    }).then( () => {
      // リストの更新
      this.fetchResponse();
      // 値の初期化
      this.refs.newText.value = "";
    })
  }
  
  // 編集機能
  updateTodo(todo) {
    fetch(`http://localhost:3001/todos/${todo.id}`, {
      method: 'PUT',
      body: JSON.stringify({
        id: todo.id,
        title: todo.title
      }),
      headers: new Headers({ 'Content-type' : 'application/json' })
    })
  }
  
  // 削除機能
  deleteTodo(todo) {
    fetch(`http://localhost:3001/todos/${todo.id}`, {
      method: 'DELETE'
    }).then( () => {
      const todos = this.state.todo.filter(item => item.id !== todo.id)
      // 保存
      this.setState({
        todo : todos
      });
    })
  }
   
  render() {
    return (
      

TODOアプリ

    {this.state.todo.map( todo => (
  • todo.title = e.target.value} /> this.updateTodo(todo)}/> this.deleteTodo(todo)}/>
  • ))}
); } } export default App;

各メソッドは以下のような内容になっています。

JSX部分

JSXでは現在のStateをli要素で表示して、値を入力フィールドに代入しています。
編集ボタンを押下時にupdateTodoメソッドを実行して、編集時にdeleteTodoメソッドを実行しています。
また、追加ボタン押下時にaddTodoメソッドを実行してTODOを追加しています。


  render() {
    return (
      

TODOアプリ

    {this.state.todo.map( todo => (
  • todo.title = e.target.value} /> this.updateTodo(todo)}/> this.deleteTodo(todo)}/>
  • ))}
); }

初期表示時

初期表示時にはライフサイクルイベントのcomponentWillMount()内でfetchResponseメソッドを実行しています。


  componentWillMount(){
    this.fetchResponse();
  }

Ajaxで情報を取得

fetchResponse()ではAjaxで取得したTODO一覧をStateにセットしています。


  fetchResponse(){
    fetch('http://localhost:3001/todos')
    .then( res => res.json() )
    .then( res => {
      this.setState({
        todo : res
      });
    })
  }

新規登録時

新規登録時にはAjaxで入力された値の更新を行ってからfetchResponse()で情報の再取得を行っています。


  addTodo() {
    fetch('http://localhost:3001/todos', {
      method: 'POST',
      body: JSON.stringify({
        title: this.refs.newText.value
      }),
      headers: new Headers({ 'Content-type' : 'application/json' })
    }).then( () => {
      // リストの更新
      this.fetchResponse();
      // 値の初期化
      this.refs.newText.value = "";
    })
  }

編集時

編集時には現在のTODO情報をPUTで送信しています。
Stateは入力のタイミングで変更されているため編集後にStateを操作する必要はないです。


  updateTodo(todo) {
    fetch(`http://localhost:3001/todos/${todo.id}`, {
      method: 'PUT',
      body: JSON.stringify({
        id: todo.id,
        title: todo.title
      }),
      headers: new Headers({ 'Content-type' : 'application/json' })
    })
  }

削除時

削除時には現在のTODO情報をDELETEで送信して削除を行います。
削除後には現在のStateから削除したTODOを取り除く必要があります。


  deleteTodo(todo) {
    fetch(`http://localhost:3001/todos/${todo.id}`, {
      method: 'DELETE'
    }).then( () => {
      const todos = this.state.todo.filter(item => item.id !== todo.id)
      // 保存
      this.setState({
        todo : todos
      });
    })
  }

これでReactでAjaxを利用することができるようなりました。
次回はReactとよく一緒に利用されるライブラリを紹介いたします。