React Netlify 公開について
ReactをNetlifyでBuildに成功した
今までledgerのようにFWでツールを作成したり
moneylogのようにhtml js css + firestoreで公開できるツールを作成したり
html css + github pages で1ページのサイトを作ったことはあるが
buildをして,その中身をwebで公開したことはなかった.なのでチャレンジ.
このサイトの通りにReactで作成したものをNetlifyのなかでdeployしてみた...
これがねっとりファイの中...暖かい...
まずは作業directoryでnpx create-react-app btest
cd btest
でreactのdefaultぐるぐるを作って入る.
GUIで専用のGithub repoを作って(privでもいける)
git init
git remote add origin git@....
git push -u origin master
ほいでgithubにpush (通らなかったからpush -f)
そしてNetlifyで自動buildしてもらう設定を組む
npm run build, build先はbuild/
そしたら通った!!!!
こんな簡単だとは!!( しかし後にcli-toolの方が早いと判明 )
ちなみに博士にこれでfirestore使えば楽チンですねって言ったら
「俺ならfirebase hosting使いこなせてないから落としますね」
って言われた,そのとおりだ... だがこれでReactでjsxを活用して
作ったSPAを手軽に公開できる手段を得た.
一応,firebase HostingではなくNetlifyを使うメリットとしては
webのGUIでgithub repo からdeployができて,second domein (hoge.netlify.app) の 設定や,bulid logが見れたりと最低限の操作がNon PGな環境でもできる点だろう.
またfirebase では作成できるprojectに限りがある問題もある
なお以前書いたこのgithub pagesでのdeployとの違いとしては
- Github アカウントとPlatformのNetlifyを分けて,Netlifyだけ職場のメアドで作れる
職場のサイトにする場合,私が退職しても私のGithubのソースから簡単にスイッチできる
Github Pagesではusernameがそのままurlになるが,NetlifyではGUIで簡単にsite name (url sub domain)を編集して即座に反映できる
- 最悪HTML CSSだけ別ツールで生成して,それをdrag and dropで持ってこれる
上記のメリットがある
またcontentfulというCMSサービスを使うと動的に中身を動かせる,ブログのようなものが作れるらしい.
Netlify CMS (not tried)
Netlify CMSという動的に動かせるNetlifyの内部サービスがある
どうdata/Workdata.jsxを組み込むのかはわからない
React props or state
分割その二
props
super(props); this.message = 'Hello from Note Component'; this.noteContent = props.noteContent; this.noteId = props.noteId;
propsのdataをclass直下に渡すことができる,??
State
constructor(props) { super(props); this.state = { notes: [ {id:1, noteContent: "Note 1 here"}, {id:2, noteContent: "Note 2 here"}, ], } }
propsとしてthisに直接書く以外に,stateとしてclassのconstructor で定義し,setStateで更新,追加することができる
props
アロー関数でもpropsは気軽に書ける。
const post = (props) => { return ( <div> <h1>{props.title}</h1> </div> )
しかしこれにはstateは入らない。
stateを宣言or使用するためにはclassを書く必要がある。
stateは変化した時に全体が再描画されるが, propsはされない。(ではなんのためにComponentWillMountがあるんだ?)
addNote(note) { this.state.notes.push(note) }
そしてComponentWillMountで更新する方法があるが,それは現在は 非推奨なので,
hooks, useState, useEffectで更新することが推奨されている
React Component の実用
why
class Componentを使用したReactでの動的サイト製作の記事
wesのReact Firebase Note App Tutorialを参考にして作っている.
index
index.js
import App from './App';
ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
基本的にはindex.htmlにlinkがあるindex.jsが起点になる
そのindex.jsでComponentの読み込み地点となる App Component(以下App)をimportし,get...Idでrenderする
App
App.jsが基本的にCotainerになる.
このApp.js自体もComponentであり,note
を描画する<Note/>
note
を追加するためのform, <NoteForm/>
を読みこむ.
Componentはclassを使い,基本的にこのように書く
App.js
class App extends Component { render() { return ( <div> <h1>React and Firebase To-Do List</h1> <Note /> </div> ); } }
file nameと同じclass nameをとり,render() { return( ) }のナカに 一つのdivを作り,そのナカにhtmlを書く.
Appではこのように他のComponentを<Hoge/>
と呼び出す
jsなので当然他のファイルから使うためには
Note.jsxでexport default Note
をして
App.jsでもNote.jsxを使うために
import Note from './Note/Note';
でexportされたComponentをimportする必要がある
そして今回はCRUDのReadの役割を果たすリスト表示のNote.jsx
は
Note.jsx
import React, { Component } from 'react'; import './Note.css'; import PropTypes from 'prop-types';
でまずReact, Component, css, PropTypesをimportする.
prop-typesは型を判定してくれる.(後述)
class Note extends Component { constructor(props) { super(props); this.message = 'Hello from Note Component'; }
ここではconstructorを書き,superをして, このComponentのなかにmessageを直接定義する.
render(props) { return( <div> <h1>{this.message}</h1> </div> ) } } export default Note;
本当はstateを使う.
今回はrenderにもpropを食わせてpropsの値を表示する.
そうするとlocalhost3kでNote.jsxのComponent fileに書かれた内容が App.jsで呼び出されてこうやって表示される
NoteForm.jsx
前回の
Appのfooter will go here...を
react, component, cssをimportし,constructorにemptyなstateを作り,
renderにinputとbtnを設ける.
NoteForm.jsx > render()
render(){ return( <div className = "formWrapper"> <input className="noteInput" placeholder = "Write a new note..." /> <button className="noteButton">Add Note</button> </div> ) }
そしてApp.jsで使えるようにNoteFormをexport default NoteForm;してimportする.
これでinputとaddが表示された
input内のvalueとread-only
NoteFormのinputのvalueを追加し,stateの中身を{}で埋め込む
<input className="noteInput" placeholder = "Write a new note..." value = {this.state.newNoteContent} />
これでこのComponentのstateのnewNoteContentがinputに 最初の読み込みに表示される.
だがこのままだとRead-Only Propertyだと警告をされる
index.js:1 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field.
なのでonChangeを書き込む必要がある.
valueと同じように{}bracketで埋め込み, 関数のtriggerにする.
onChange
constructorのbracketの閉じた後にhandle関数を仕込む.
handleUserInput(e) { this.setState({ newNoteContent : e.target.value, }) }
これをrenderのinputのなかにonChangeで
onChange = {this.handleUserInput}
と仕込むと,このinputの中が変更されるたびにhandleUserInputがその中の valueで起動する.
だがこのままではCannot read property 'setState' of undefined
なので
constructorの中にbindする.そうすると使える.
constructor(props) { super(props); this.state = { newNoteContent: 'New Note Content', } this.handleUserInput = this.handleUserInput.bind(this); }
ここでhandleUserInputにconsole.logでthis.stateを吐かせると
変更されるたびに中身を吐き出してくれる.
これがstateと連携したonChangeのhandleだ
これでGUIでinputからstateを変更できるようになる.
次は同じようにして,btnにonClickを仕込む.
btnにonClickをつけwriteNoteのtriggerにする
btnも同じようにrenderのタグ内に仕込む
<button className="noteButton" onClick = {this.writeNote} >Add Note</button>
propsには{}を使い,関数名の後に()はつけない.
setState({})を使ってstateを操作する関数を追加する.
writeNote(){ this.setState({ newNoteContent: '', // empty input box }) }
constructorの後にwriteNoteのfuncを書く.
とりあえずnewNoteContentをemptyにする処理を入れておく
this.writeNote = this.writeNote.bind(this);
そして先ほどと同じようにbind(this)する.
すると押すとinputの中にvalueで紐づけられているnewNoteContentというstateが
空のstringになるwriteNoteが起動するbuttonが完成する.
考えたらこれは動作テストで入れてる処理ではなく,「DBへの追加処理が発生したら 入力欄を空にする」という当たり前に必要なMethodだった.これがないからFirebaseとjQで作った家計簿アプリは「btnを押した時に追加した手応えがなくて連続押して,二つ同じものが入ってしまう」ということが起こりがちだったんだな
(悪い例: https://moneylog-e7c4b.firebaseapp.com/ )
NoteFormとAppの連携
AppでAppのstateにpushするaddNote()を作成してNoteFormのwriteNoteで使用させる.
ここではNoteForm Componentに作成したwriteNoteのなかにaddNoteを使用し,
そのaddNoteはApp.jsに書く.NoteFormのstateではなく,Appのstateに入れるためだ.
addNote(note) { this.state.notes.push(note) }
これでstateの中のnotesというarrayを引数でとったnoteに追加する.
this.addNote = this.addNote.bind(this);
handleやwriteの関数と同じように,Appのconstuctorのナカでbindする.
また,これだけではNoteFormで使えないので,
renderにある
<NoteForm addNote={this.addNote}/>
という形addNoteの関数をNoteFormに渡す.
NoteForm use addNote
そしてNoteFormで使う.
writeNote(){ this.props.addNote(this.state.newNoteContent); this.setState({ newNoteContent: '', // empty input box }) }
Appのrenderの中で渡されたthis.addNoteはthis.propsの中にはいるので取り出し
ここNoteFormのstateの中にあるnewNoteContentをaddNoteを使って
Appのstateのnotesにpushする.
これでaddNoteにconsole.logを仕込んで見るとnotesは一つ増えているのが見える
0: {id: 1, noteContent: "Note 1 here"} 1: {id: 2, noteContent: "Note 2 here"} 2: "New Note Content" length: 3 __proto__: Array(0)
だが画面の更新はされない.
previous noteを挟む
ここでaddNoteの処理に一つ噛ませる
addNote(note) { const previousNotes = this.state.notes; previousNotes.push({ id: previousNotes.length + 1, noteContent: note, }); this.setState({ notes: previousNotes, }) console.log(this.state.notes); }
previousNotesという変数にstateのnotesを入れてから
その変数に引数でとった追加する内容であるnoteを
noteContentとして, さらに現在の追加さき配列notesの次の添字をidとして
pushする.
最後にnotesにpreviousNotesの内容を入れる.
stateに直接値を入れては行けないからsetState({})を使用する.
回りくどく見えるが,stateを更新する処理を別の処理と分割するためにpreviousNote介する.長くなってきた時にわかる.
さらにreact特有のkeyを渡す必要が出てくる.これがないとエラー.
render, give state id, content, key,
だからApp.jsのrenderでnotesをmapで展開して,Note Componentにkey, id, Contentを渡すことで描画している.
これでlocalなReactのstateにinputを介して追加して,それを即座に更新して 表示することができるようになった.
conclude
おさらいすると,<App />
のstateにidとcontentのobjをもつ配列notesを作成.
renderではそのstateにあるnotesをmapで展開し,id, key = id, contentを
<Note />
に渡す.<Note />
ではconstructorでpropsから受け取り,
renderでcontentを表示する.そこにcssがかかってカードになる.また
propTypesによって型がstringかチェックが入る.
追加, ADD編ではaddNoteという関数をAppのconstructorの後に作り,
stateのnotesに配列の長さ+1でid,引数をcontentにpushする.
それを変数を介してsetStateし,この関数addNote()を<NoteForm />
に私,
propから受け取り,inputのvalueにstate newNoteContentを組み込み,
onChangeでhandleしてe.target.valueからnewNoteContentに渡し,
btnのonClickで先ほど<App />
からもらったaddNoteをpropから使って
addNoteにnewNoteContentを渡し,今inputのvalue に入っている
newNoteContentを空にする.
ReactはここでRenderが更新される.
これでCRUDのRead, Create, Updateの処理までができた.
これではbrowserをrefleshした時にstateに入れたdataも消えてしまうから,Firebaseに保存し,起動した時にFirebaseから値を取ってくる物にする.
その後,moneylogのようにhttpsでアクセスできるようにfirebase hostingを活用する.
React + Firebase app duplicate error
background
3years agoの wesのrepositoryと解説を頼ってfirebase + Reactのcrudを作ろうとした.
jQで掲示板もどきを作った時とは違うfirebaseの使い方,config fileを噛ませる
やり方になっている.
Frond End のReactのstateのところではうまくいったが,Firebaseとの接続で
この動画のとうりにやると,
Uncaught FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
のErrorが出てしまった.
cause
nextで上がっているこのissueは関係なかった.
2018年のこの記事のコードと差分をとって原因が判明した.
原因は
App.jsのナカでfirebase.initializeApp(config);
をしていたのと
firebaseのdatabaseを使っていたことだろう.
2020現行verではApp本体でinitするのはダメになっているようだ.
またfirebaseにdatabaseが無くなって,firestoreになっている.
なのでwesの該当コードを次のように書き直した.
code (in src/)
Config/config.js (BEFORE)
export const DB_CONFIG = { apiKey: "-hoge", authDomain: "hogehoge.firebaseapp.com", ......... };
最初はfirebaseのget web appからとってきた値を変数に入れてexportするだけで
initはApp側でやらせていた.これを
Config/config.js (AFTER)
import firebase from 'firebase/app'; import 'firebase/firestore'; const config = { apiKey: "-hoge", authDomain: "hogehoge.firebaseapp.com", ......... }; const firebaseApp = firebase.initializeApp(config); export const firestore = firebaseApp.firestore();
firebase, firestoreをconfig内でimportしてきて,
configでinitしたものにfirestoreも噛ませてexportする.
App.js (BEFORE)
import { DB_CONFIG } from './Config/config'; import firebase from 'firebase/app'; import 'firebase/database'; class App extends Component { constructor(props){ super(props); this.app = firebase.initializeApp(DB_CONFIG); this.database = this.app.database().ref().child('notes'); .................
従来はconfig のkeyとかをそのまま変数に入れてexportしてきたものを
DB_CONFIGとしてimportしてこちらでinitしていたが,それではエラーが出るので
config.js側でinitをするようにした.
またどうもfirebaseのversionが変わってdatabaseがfirestoreという名称に
なったようなので,databaseを使うのをやめた.
AFTER
import { firestore } from './Config/config'; import firebase from 'firebase/app'; import 'firebase/firestore'; class App extends Component { constructor(props) { super(props); this.app = firebase.app(); this.db = firebase.firestore(); console.log(this.db);
firestoreという名前にしてinitが住んでfirestoreもかまされたものをconfigからimport
firebase/databaseをやめてfirebase/firestoreを持ってきた
これでconsole.logすると
t {GT: FirebaseAppImpl, zT: t, INTERNAL: {…}, KT: t, XT: "[DEFAULT]", …} hm: (...) app: FirebaseAppImpl GT: FirebaseAppImpl {firebase_: {…}, isDeleted_: false, name_: "[DEFAULT]", automaticDataCollectionEnabled_: false, options_: {…}, …} zT: t {Qr: Promise, Wr: false, jr: Array(0), Kr: null, Gr: false, …} INTERNAL: {delete: ƒ} KT: t {projectId: "note-app0902", database: "(default)"} XT: "[DEFAULT]" ZT: t {currentUser: t, I: true, R: 1, u: null, m: ƒ, …} tm: n {} em: t {host: "firestore.googleapis.com", ssl: true, credentials: undefined, timestampsInSnapshots: true, cacheSizeBytes: 41943040, …} sm: t {serializer: t, Pa: ƒ} __proto__: Object
が入っているので,これで接続が直せた!!
firestoreとdatabase
そもそもBack Endをfirebaseでやると一括りに説明されがちだが,
firebaseにはDBのfirestore, databaseがあり,さらにimgのstorageがある.
//カヤックさん丁寧な解説すごいな,エントリーしようかな
説明ではweb GUIでfirebaseのサイトのdatabaseタブからdatabaseが作成されていたが,現在はdatabaseタブを開くと大きくfirestoreが表示される.
私はfirestoreを作りながらdatabaseを呼び出していたらしい.
まぁfirestoreとか使う前にconfigでinitする段階でエラー出ていたから今回のエラーの 解決には関係ないけどね..onとか.pushとかdatabaseで使えていたメソッドがfirestoreで使えないのには注意が必要だ.
firebase全く簡単じゃないな....
Choose a Database: Cloud Firestore or Realtime Database | Firebase
システム, コンポーネント設計について
sytem component architecture
component arch, コンポーネント設計
why
やめたろう さんの記事を読んだ
<v-btn rounded depressed min-width="120" large outlined @click="cancel" > キャンセル </v-btn> <v-btn rounded depressed min-width="120" large color="primary" @click="ok" > OK </v-btn>
このOK buttonとCancel buttonを各自component化しないと
複数ページ帰るときにぐちゃぐちゃになるというエピソード.
<CancelButton @click="cancel" /> <OkButton @click="ok" />
こうして使えばroundedを消すときに一斉痴漢より
遥かに安全に置換ができる
また,全てのページで使っているならば
/components/Heading2.vue <template> <h2 class="heading2"> <slot /> </h2> </template>
のようなとても小さいtag群すらもcomponentを作るメリットが
十分にある.
conclude
まとめると,徹底的にcomponentにしていくことで,仕様変更に非常に強く,
壊れる可能性が低いメンテナンス性の高いサイトが作れるということだった.
これだけだとどの設計書にも書いてありそうだが,非常にシンプルで具体的で
尚且つジョークも豊富でストンと理解できた.
彼の記事は非常にわかりやすい.
system-design-primer
https://github.com/donnemartin/system-design-primer/blob/master/README-ja.md
これを読んでまとめる
Twitterで流れてた
https://github.com/donnemartin/system-design-primer/blob/master/README-ja.md
Bought Udemy React Course
background
今まではYoutube Premireに1.4k / M 課金していることもあり
前述の記事のようなReact Tutorialをやっていた.
しかしながら先日ふとUdemyで1.4kのコースを購入し,
やっているときにこんなツイートを目にした.
This Tweet is unavailable.
....消すほどか??まぁ,有料のリソースの方が時間効率がいいという容姿だ.
そこで実際にYoutubeの無料教材とUdemyの有料教材の違いを意識してみると,
思った以上に質が違った.もちろんYoutubeのCrash Courceも非常に丁寧だが,
Udemyでは:
* 解説で喋ってる人が背景を切り抜いてジェスチャーだけが伝わるようになっている
* 音質がとにかく良い,
* 短く分割して何をやっているのか明確になっている
などが上質で時間効率の良さを感じた.適宜追加していこうと思う. 2020.04.16では04までしか進んでないしね.
https://www.udemy.com/share/101WbyAEIZdldTTXoF/
props.childrenでは中身はでない?
基本はstateの配列をthis.state.hoge[0].age の形で展開 若しくはmapで展開。
renderにonclickを仕込んでhandlerを設定。
stateの値を直接書き換えては行けない temp変数に入れる処理を書いた後に setStateを使ってその変数をstateに入れる。
だけどこれでhandler作るだけだとreloadが必要だから Component Mount系が必要なのかなー?
hooks, useState
useStateをimportして、 これを使ってstateを初期化する。 AppでComponent/ costructorの代わりに
let Person = props => { useState({ Persons : [ ] }) }
とある大阪の人事さんの友人に面接をみてもらった!
## 経緯 フォロワーの関西のSES会社の人事の方と話す機会があって,なんでも相談乗ってやーって言ってくれていたので,第一志望のソ●トブレーンに落ち,9社落選が積み重なっている今,喋り方に問題があるのか不満になって時間とってskypeで見ていただいた
事故紹介
なぜなりたいか,何がしたいかを説明した
Feed Back
- 話が長い.結論を企業は求めている.前提が長い.君の話はそれを意識すれば1/3で済む
- 企業が知りたいのは結果であり,それに対する肉付けを意識しろ
updated
- 新しいやり方が好き,できることが増え,楽しいのがソフトウェアエンジニア.
- どの端末でも作業できてwebで完結するシステムなら(順番待ちや手作業の時間ロス,嵩張る紙の場所ロス,目視手計算 書き写しミス,)でのロスが減らせると思った
- -> だから簡単に誰でも使えて安価な作業ツールが作りたい
長所
よくある質問を実際にしてもらった.実際に手を動かしてものを作れるって言った
Feedback
- 話すときに主語の回数が多い,自分が,自分が,自分が...って言ってるのを 自分でこれを作ることを企画して,設計して,改善して,作り直して...って言った方がいい 必死になってる(素人)感が伝わってしまう
- だが逆にその下手さを逆手にとって,言葉が下手で,自己分析しすぎてしまうとか
笑いに変える?といいかも
updated
- 設計と計画と改善を自分で行ってcakeのs
短所
これ言ったら受からなそうだから言わなかった「入力ミスが多い」を言ってみた
Feedback
- プログラミングでのエラー出て直す経験を通して改善されてることをいうべき
- 単調な作業 => 改善するためのツールが思いつくなどで切り返す
やりたいこと
前線で開発がやりたいといった
Feedback
- コード書きたいばかりは良くない
- 下積みからできないやつだと思われてしまう.テスターやる
- ただ内定は企業は取り消せないから,契約書類をちゃんと見て,別の部署だったら 何年で戻れると明記しろと言うべき.
Feedbackまとめ
とにかく不利なことを言うときは切り返すのが大事.前述のように. あとスキルを聞かれた時に「できると言ったら嘘になる.だがこれから学んでいっている (入社後?)できるようにしろと言われたらする」など
エージェントに関して
むやみにエージェントを使っているのが勿体無い.
採用時に会社からエージェントに年収の1/3(1M)が支払われる契約はGreenなど媒体に1 week 500kで出して.4人採用するのと比べてコスパが悪い
エージェントを使っている学生を忌避するが,広告のためにエージェントに登録している企業も多い.いきなりやめろとは言わないが,自分でも申し込む方が良い.エージェントが持っている企業には限りがある.学生を金としてみている傾向が強い.モダンなベンチャーは使っていない企業が多い.ソ●トブレーンの規模では同じあれがある可能性が高い
ソ●トブレーン ハラスメント疑惑
職業選択の自由があるんだから,(最終選考前に)うちに受かったら他の選考をキャンセルして欲しいといったのは違法.そこまでの強権を人事が振るうところだと,配属先なども人事の力が強すぎて一切希望が通らないかもしれない.
面接面談含めて7回あったのは全て面接と取っていい. だがその中で人事がプライバシーに突っ込んで上から目線で逃げ場のない意見の押し付けをする行為もハラスメント.( 学生が質問を無視できない人事の立場を利用して、ズイズイひとのプライバシーに踏み込んできた挙句に、あたしは佐藤さんの意見こうだと思うんですよ!そうですよね!だからうちに向いてると思うし前回の選考受かったんですよね!と否定したらうちに向いてないことだぞと暗に示すような「質問」)
でかい老舗自社開発は部門が多いから開発以外に回されやすい.
普通面接はいい印象で終わるべきなのに他社の選考キャンセルとプライバシーハラスメントをぶち込んでくるのはやばい
やはりでかい企業はどうしても立場が強くなって,大企業病?のパワハラ横行?圧迫面接などが起きがちだから逆にエージェントに1M払えないような小さい受託がおすすめ.
その他媒体などを教えてもらった!!
長く丁寧にほんと助かりました!!!