0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React.js & Next.js超入門のチャプター6を改変:Firestore使用するようにした②

Last updated at Posted at 2020-04-14

#React.js & Next.js超入門のチャプター6を改変:Firestore使用するようにした②


React.js & Next.js超入門

はなかなか良い本なのだが、最後のチャプター6「Firebaseでデータベースを使おう」でFirestoreでなくRealtime Databaseを使ってる。なので買うのを躊躇した人いるかもと思ってFirestoreを使用するコードに変えてみた。

React.js & Next.js超入門のチャプター6を改変:Firestore使用するようにした①からのつづき、
セクション6-2

####▼リスト6-6 store.js
Firebaseへの接続情報を.config.jsに逃がすので以下のように変更(理由は.gitignoreに.config.jsを記述したいため)

import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import firebase from "firebase";
import "firebase/firestore"; 
import { firebaseConfig } from './.config';

// Firebaseの設定. initializeApp()は一度だけ実行させたいので、一度だけ呼ばれるstore.jsに記述する.
try {
  firebase.initializeApp(firebaseConfig);
} catch (error) {
  console.log(error.message);
}
const db = firebase.firestore();
export { db };


//// 以下はRedux処理.あくまで参考でここでは使用していない.
// ステート初期値
const initial = {
}

// レデューサー(ダミー)
function fireReducer(state = intitial, action) {
  switch (action.type) {
    // ダミー
    case 'TESTACTION':
      return state;
    // デフォルト
    default:
      return state;
  }
}

// initStore関数
export function initStore(state = initial) {
  return createStore(fireReducer, state, 
    applyMiddleware(thunkMiddleware))
}

プロジェクトルートに.config.jsファイルを作成し以下のように。

export const firebaseConfig = {
  apiKey: " APIキー ",
  authDomain: "プロジェクト.firebaseapp.com",
  databaseURL: "https://プロジェクト.firebaseio.com",
  projectId: "プロジェクト",
  storageBucket: "プロジェクト.appspot.com",
  messagingSenderId: " ID番号 ",
  appId: ""
};

####▼リスト6-7 fire.js
本の通り

####▼リスト6-8 fire_find.js
本の通り

####▼リスト6-9 FireFind.js
以下の通り。import~の部分と、// 検索の実行コードを変更

import React, {Component} from 'react'
import {db} from "../store";

class Firefind extends Component {
    style = {
      borderBottom:"1px solid gray"
    }
  
    // 初期化。ステートとイベント用メソッドの設定
    constructor(props) {
      super(props);
      this.state = {
        input:'',
        data:[]
      }
      this.doChange = this.doChange.bind(this);
      this.doAction = this.doAction.bind(this);
    }
  
    // 入力フィールドに入力時の処理
    doChange(e){
      this.setState({
        input:e.target.value
      })
    }
  
    // ボタンクリック時の処理
    doAction(e){
      this.findFireData(this.state.input);
    }
  
    // 検索の実行
    findFireData(s){
        db
          .collection("sample")
          .where("ID", "==", s)
          .get()
          .then(querySnapshot => {
              const items = querySnapshot.docs.map(doc => doc.data());
              this.setState({ data: items })
          });   
    }
  
    // テーブルの内容の作成
    getTableData(){
      let result = [];
      if (this.state.data == null || this.state.data.length == 0){
        return [<tr key="0"><th>NO DATA.</th></tr>];
      }
      for(let i in this.state.data){
        result.push(<tr key={i}>
          <th>{this.state.data[i].ID}</th>
          <th>{this.state.data[i].name}</th>
          <td>{this.state.data[i].message}</td>
        </tr>);
      }
      return result;
    }
  
    // レンダリング
    render(){
      return (<div>
        <input type="text" onChange={this.doChange}
          style={this.style} value={this.state.input} />
        <button onClick={this.doAction}>Find</button>
        <hr />
        <table><tbody>
          {this.getTableData()}
        </tbody></table>
      </div>)
    }
  }
  
    export default Firefind;

####▼リスト6-10 fire_add.js
本の通り

####▼リスト6-11 Fireadd.js
import~と、// 最後のIDを取得、および// データを追加する のコードを変更

import React, {Component} from 'react'
import {db} from "../store";
import Router from 'next/router';

class Fireadd extends Component {
    style = {
      fontSize:"12pt",
      padding:"5px 10px"
    }
  
    // 初期化処理
    constructor(props) {
      super(props);
      this.state = {
        name_str:'',
        msg_str:'',
        lastID:-1,
        data:[]
      }
      this.getLastID(); // 最後のIDのチェック
      this.doChangeName = this.doChangeName.bind(this);
      this.doChangeMsg = this.doChangeMsg.bind(this);
      this.doAction = this.doAction.bind(this);
    }
  
    doChangeName(e){
      this.setState({
        name_str:e.target.value
      })
    }
    doChangeMsg(e){
      this.setState({
        msg_str:e.target.value
      })
    }
    doAction(e){
      this.addFireData();
      Router.push('/fire');
    }
  
    // 最後のIDを取得
    getLastID(){
        db
          .collection("sample")
          .orderBy('ID')
          .limitToLast(1)
          .get()
          .then(querySnapshot => {
              const items = querySnapshot.docs.map(doc => doc.data());
              console.log('itemsは■' + JSON.stringify(items));
              const itemID = items[0].ID; // 配列構造のJSONデータitemsからID部分だけをとりだす
              console.log('itemIDは■' + itemID);
                this.setState({
                    lastID:itemID
                  });
          });   
    }
  
    // データを追加する
    addFireData(){
        if (this.state.lastID == -1){
            return;
        }
        let id = this.state.lastID * 1 + 1; //ここで * 1 + 1の処理をしたことでidは数値型になった。
        console.log('idは■' + id);
        let stringed_id = String(id); // ここでString型にしないとFunction CollectionReference.doc() requires its first argument to be of type non-empty string, but it was:... エラー
        console.log('stringed_idは■' + stringed_id);
        const docRef = db.collection("sample").doc(stringed_id);
        docRef
          .set({
            ID: stringed_id,
            message: this.state.msg_str,
            name: this.state.name_str
          });           
    }
  
    // レンダリング
    render(){
      if (this.state.lastID == -1){
        this.getLastID();
      }
      return (<div>
        {(this.state.lastID == -1)
        ?
        <p>please wait...</p>
        :
        <table>
        <tbody>
          <tr>
            <th className="label">name</th>
            <td><input type="text" placeholder="your name."
              onChange={this.doChangeName}
              value={this.state.name_str} /></td>
          </tr>
          <tr>
            <th className="label">message</th>
            <td><input type="text" size="40"
              placeholder="type message..."
              onChange={this.doChangeMsg}
              value={this.state.msg_str} /></td>
          </tr>
          <tr><th></th><td>
          <button onClick={this.doAction}>Add</button>
          </td></tr>
        </tbody>
        </table>
        }
      </div>)
    }
  }
  
  export default Fireadd;

####▼リスト6-12 fire_del.js
本の通り

####▼リスト6-13 Firedelete.js
import~と、// 項目の削除 のコードを変更

import React, {Component} from 'react'
import Router from 'next/router';
import {db} from "../store";

class Firedelete extends Component {
  style = {
    fontSize:"12pt",
    padding:"5px 10px"
  }

  // 初期化処理
  constructor(props) {
    super(props);
    this.state = {
      id_str:'',
    }
    this.doChange = this.doChange.bind(this);
    this.doAction = this.doAction.bind(this);
  }

  doChange(e){
    console.log('doChangeの中' + e.target.value);
    this.setState({
      id_str:e.target.value
    })
  }

  doAction(){
    this.deleteFireData();
    Router.push('/fire');
  }

  // 項目の削除
  deleteFireData(){
    let id = this.state.id_str;
    console.log('■id: ' + id);
    db
    .doc("sample/" + id)
    .delete()
    .then(() => {
        console.log('削除しました')
    })
  }

  // レンダリング
  render(){
    return (<div>
      <table>
      <tbody>
        <tr>
          <th className="label">ID:</th>
          <td><input type="text" placeholder="delete ID:"
            onChange={this.doChange}
            value={this.state.id_str} /></td>
        </tr>
        <tr><th></th><td>
        <button onClick={this.doAction}>Delete</button>
        </td></tr>
      </tbody>
      </table>
    </div>)
  }
}

export default Firedelete;

以上。


[React.js & Next.js超入門のチャプター6を改変:Firestore使用するようにした③](https://qiita.com/atomyah/items/f9a632ca1302d936324c) につづく
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?