katekichiのゆるブログ

普段の作業メモや日常の出来事とか

「Electronではじめるアプリ開発」を写経してみた ⑥

またかなり間が空いてしまったのと、写経したものの期待通りの動きではなく調査しましたが 以下の理由からかなりハマってしまっていました。

  1. Electron上でのReactのDebug方法を確立できていなかった。

  2. ES2016と、Promiseの理解不足から原因の特定に時間が掛かった。

  3. そもそもFirebaseのお作法が分かってなく、原因の特定に時間が掛かった。

※1.に関しては、以下を参考にしてDebug環境の構築をしたいと思います。 qiita.com

※2. 3.の課題については別途調査してまとめようと思います。

今回は、チャットルーム一覧の実装から

src/renderer/Rooms.jsx

import React from "react";
import { hashHistory } from "react-router";
import RoomItem from "./RoomItem";
import firebase from "firebase/firebase-browser";

const ICON_CHAT_STYLE = {
    fontSize: 120,
    color: "#DDD"
};

const FORM_STYLE = {
    display: "flex"
};

const BUTTON_STYLE = {
    marginLeft: 10
};

export default class Rooms extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            roomName: "",
            rooms: []
        };
        this.db = firebase.database();
        this.handleOnChangeRootName = this.handleOnChangeRootName.bind(this);
        this.handleOnSubmit = this.handleOnSubmit.bind(this);        
    }

    componentDidMount() {
        this.fetchRooms();
    }


    handleOnChangeRootName(e) {
        this.setState({ roomName: e.target.value });
    }

    handleOnSubmit(e) {
        const { roomName } = this.state;
        e.preventDefault();

        if (!roomName.length) {
            return;
        }

        // Make new Chatroom for a Firebase 
        const newRoomRef = this.db.ref("/chatrooms").push();
        const newRoom = {
            description: roomName
        };

        newRoomRef.update(newRoom).then(() => {
            this.setState({ roomName: "" });
            return this.fetchRooms().then(() => {
                hashHistory.push(`/rooms/${newRoomRef.key}`);            
            });
        });
    }

    fetchRooms() {
        return this.db.ref("/chatrooms").limitToLast(20).once("value").then(snapshot => {
            const rooms = [];
            snapshot.forEach(item => {
                rooms.push(Object.assign({ key: item.key }, item.val()));
            }); 

            this.setState({ rooms });  
        });
    }

    // Drawing the left pane 
    renderRoomList() {
        const { roomId } = this.props.params;
        const { rooms, roomName } = this.state;
        return (
            <div className="list-group">
                { rooms.map(r => <RoomItem room={r} key={r.key} selected={r.key == roomId} />)}
                <div className="list-group-header">
                    <form style={FORM_STYLE} onSubmit={this.handleOnSubmit} >

                        <input 
                            type="test"
                            className="form-control"
                            placeholder="New room"
                            value={roomName}
                            onChange={this.handleOnChangeRootName}
                        />

                        <button className="btn btn-default" style={BUTTON_STYLE}>
                            <span className="icon icon-plus" />
                        </button>
                    </form>
                </div>
            </div>
        );
    }

    // Drawing the right pane 
    renderRoom() {
        if (this.props.children) {
            return this.props.children;        
        } else {
            return (
                <div className="text-center">
                    <div style={ICON_CHAT_STYLE}>
                        <span className="icon icon-chat" />
                    </div>
                    <p>
                        Join a chat room from the sidebar or create your chat room.
                    </p>
                </div>                                                
            );
        }
    }

    render() {
        return (
            <div className="pane-group">
                <div className="pane-sm slider">{this.renderRoomList()}</div>
                <div className="pane">{this.renderRoom()}</div>                
            </div>
        );
    }
}

以下は、チャットルーム一覧の個々のアイテムの実装

src/renderer/RoomItem.jsx

import React from "react";
import { Link } from "react-router";

const LINK_STYLE = {
    color: "inherit",
    textDecoration: "none"
};

export default function RoomItem(props) {
    const { selected } = props;
    const { description, key } = props.room;
            
    return(
        <div className={selected ? "list-group-item selected" : "list-group-item"}>
            <Link to={`/rooms/${key}`} style={LINK_STYLE}>
                <div className="media-body">
                    <strong>{description}</strong>
                </div>
            </Link>
        </div>
    );
}

ルームを追加すると一覧に登録されることが確認できました。 f:id:katekichi:20170614001823p:plain f:id:katekichi:20170614001827p:plain

Firebaseのchatroomsにも登録されました。 f:id:katekichi:20170614001831p:plain f:id:katekichi:20170614001834p:plain

今回はここまで!!

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

JavaScript フレームワーク入門

JavaScript フレームワーク入門