JavaScriptだけでWebサイト開発

node.js + Express + mongodb系 + React でサービスを作るメモ

create-react-app で React フロントエンドの掲示板を作ってみる(投稿)

前回の続きです。

フォームを表示して、投稿をできるようにします。

作るもの

  • これまで作ってきた掲示板と同じもの
  • フロントエンドが今回作るもの。前回作った掲示板APIと連携して書き込みデータをやりとりする。

サーバーAPIを立ち上げておく

前前回作った「掲示板REST API」を localhost:3000で立ち上げておきます。このサーバーと 今回作るアプリが連携します。

開発環境

1. App.jsにコンポーネントを追加

App.js

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

/**
 * 書き込み1件
 */
class Post extends Component {
    render() {
        return (
            <div className="kakikomi">
                <div>{this.props.post.kakikomi}</div>
                <p className="name">{this.props.post.name}</p>
            </div>
        );
    }
}

/**
 * 書き込みリスト
 */
class List extends Component {
    // 書き込みリスト
    render() {
        const posts = this.props.posts;
        var list = [];
        
        // map
        for (var i in posts) {
            list.push( <li key={i}><Post post={posts[i]} /></li> );
        }
        return (<ul>{list}</ul>);
    }
}

/**
 * 投稿フォーム
 */
class UpForm extends Component {
    constructor(props) {
        super(props);
        this.state = {
            kakikomi:'',
            name:'',
            message:'書き込んでください'
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    handleSubmit = (e) => {
        e.preventDefault();
                           
        // サーバーAPIにJsonでPOSTする
        fetch('/api/v1/Post', {
            method : "POST",
            headers: {
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
            body: JSON.stringify({
                kakikomi: this.state.kakikomi,
                name : this.state.name
            })
        }).then(data => {
            this.setState({
                message:'アップしました',
                kakikomi: '',
                name: ''
            });
        }).then(() => {this.props.onSubmit()});
    }

    // フォームの値とstateをbindする役割
    handleChange = (e) => {
        this.setState({message:''});
        this.setState({ [e.target.name] :e.target.value});
    }

    render() {
        return  (
            <div className="form">
                <p>{this.state.message}</p>
                <form onSubmit={this.handleSubmit}>
                  <label>内容</label>
                  <textarea name="kakikomi" value={this.state.kakikomi} onChange={this.handleChange}></textarea>
                  <label>名前</label>
                  <input type="text" name="name" value={this.state.name}  onChange={this.handleChange} />
                  <button type="submit">投稿</button>
                </form>
            </div>
        );
    }
}

/**
 * ヘッダー
 */
class Header extends Component {
    render() {
        return (
            <header>
                <h1>掲示板</h1>
            </header>
        );
    }
}

/**
 * 全画面
 */
class App extends Component {

    constructor(props) {
        super(props);
        this.state = {
            // 書き込み一覧
            posts: []
        };
        this.updatePosts();

        this.updatePosts = this.updatePosts.bind(this);
    }

    // 書き込み一覧を最新状態にする
    updatePosts(e) {
        getPost((data) => {
            this.setState({posts: data});
        });
    }

    render() {
        return (
            <div className="App">
                <Header />
                <UpForm onSubmit={this.updatePosts}/>
                <List posts={this.state.posts}/>
            </div>
        );
    }
}

/**
 * サーバーから書き込み一覧を取得する
 * @method getPost
 * @param  {Function} callback データ取得後のコールバック
 * @return {[type]}
 */
function getPost(callback) {
    fetch('/api/v1/Post?sort={"_id":-1}')
        .then(response => response.json())
        .then((data) => {callback(data)});
}

export default App;

やったこと

  • コンポーネント
    • Header : ヘッダー
    • UpForm : 投稿フォーム
    • List : 書き込みリスト
  • フォームの入力と同時ににstateに値を更新
  • フォームのイベント処理でAPIに書き込みをPOSTする

ブラウザでの動作

  • 初期表示でフォームと書き込み一覧をを表示
  • フォームに入力して「投稿」押すとリストのトップに追加される

2. まとめ

  • サーバーサイドのAPIとcreate-react-appで作成したブラウザクライアントが連携した掲示板
  • サーバーサイドAPIは前前回作った掲示板API
  • クライアントをスマホアプリにする場合はReact Nativeにする

github

ソースはこちらにあります(tag:v1)

github.com

©ichi-bit