Make-2ch-log
まずAppの中身をCLEAR
Bootstrap4をnpmで食わせる
npm i bootstrap
4.4.1が入った
npm i react-bootstrap
これも必要?1.01が入った
import 'bootstrap/dist/css/bootstrap.min.css';
これをimportして
import Button from 'react-bootstrap/Button';
btnで試してみる
<Button variant="primary">Primary</Button>{' '}
Appのrenderにこれを書いたら読み込まれた!
[f:id:kei_s_lifehack:20200507051109p:plain]
[https://react-bootstrap.github.io/components/table/:embed:cite]
Reactだとかなりsimpleにbootstrapがかける
[f:id:kei_s_lifehack:20200507051254p:plain]
しかし2chのUIはこれ
[f:id:kei_s_lifehack:20200507052547p:plain]
tableのUIはこれ
[f:id:kei_s_lifehack:20200507052610p:plain]
次の行にcontentsかけないし,columnの幅も調整できん
grid三つ書くしかないか?
[f:id:kei_s_lifehack:20200507120627p:plain]
思ったよりいい感じになった
import React from 'react'; import Writing from './components/Writing'; function App() { return ( <div> <Writing/ > </div> ); } export default App;
App側を簡単にかけるの便利だ
Database
まずはconsoleでfirestoreで
Add Firebase to Your AppのところでNick Name
firestoreを書いていく まずは src/Config/config.jsに
Add Firebase to Your AppのところでNick Name
npm i firebase
import firebase from 'firebase/app'; const firebaseConfig = ... { apiKey = xxxxxx; const firebaseApp = firebase.initializeApp(config); export const firestore = firebaseApp.firestore(); ..... }
これをfirestoreとしてWritingでimport
refにuseStateを使ってみよう!!
constructor直下に
this.ref = firebase.firestore().collection('notes');
で書いていたのを
const [ref, setRef] = useState[ firebase.firestore().collection('writings')];
に置き換える
useEffectがわからんが,どうやらcomponentWillMountに近いものらしい
[https://qiita.com/keiya01/items/fc5c725fed1ec53c24c5#%E8%89%AF%E3%81%84%E4%BE%8B-3:embed:cite]
この記事によると
useEffect( () => { const time = setInterval(() => { dispatch({ type: "ADD_COUNT" }); }, state.tick); return () => clearInterval(time); }, [ state.tick ] );
これでstate.tickが変化するたびに「副作用」として処理を追加できるらしい
function Example() { const [count, setCount] = useState(0); // Similar to componentDidMount and componentDidUpdate: useEffect(() => { // Update the document title using the browser API document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
公式にはこのような記載がある.htmlのtitleも変更できるようだ
このコードでは[]に最後に入れてないから,何も入れてなければbrowser APIで何か 変数が更新されたのを検知してuseEffectをうごかすのだろうか.
TypeError: storeRef.onShapshot is not a function (anonymous function) src/components/Writing.jsx:37 34 | 35 | useEffect( 36 | () => {
37 | let unsub = storeRef.onShapshot( | ^ 38 | update 39 | ); 40 | }
storeRef.onShapShotがuseEffectではとれない....
storeRefの中身は確認してある.hooksでclassのやり方はできないようだ
全部はわからんがここのコードを使ってみる
export const createWrintings = (writings) => { return storeRef.add({ created: firebase.firestore.FieldValue.serverTimestamp(), content: writings, }); };
create, addは簡単に作れた.stateは使わないようだ
SHOWができないから
これを使ってみる
react-firebase-hooks というツールを使う
npm install --save react-firebase-hooks
Writing.jsxにはいつもの
import firebase from 'firebase/app'; import { firestore } from '../Config/config';
の他に
import {useCollectionData} from 'react-firebase-hooks/firestore';
をしてさっきnpm i したのを読んで
const [values, loading, error,] = useCollectionData( ref, {idField: 'id'});
で設定する
if(loading) { return <div>Loading...</div> } if(error) { return <div>{`Error: ${error.message}`}</div> }
loading, errorではこれらを返し
return ( <ul> {values.map(value => ( <li key = {value.id}>{value.content}</li> ))} </ul> )
return ではvalueをmapするだけ doc...とか一切必要がない
これだけでfirestore collectionからDOMに書き込めた
valuesをcllすると
(2) [{…}, {…}] 0: {created_at: t, content: "俺みたいな中3でグロ見てる腐れ野郎、他に、いますかっていねーか、はは", id: "KwONQGM2AyLohkGOTF3u"} 1: {created_at: t, content: "初カキコ,ども...", id: "LIGRzMJJdxM1pJAo5R3L"} length: 2 __proto__: Array(0)
ちゃんと入っている!!!これをcreated_atでsortすれば行けそうだ.
idFieldでidを取得するところがポイントです。
と書いてある通りに,doc.idがdoc.data()と並列で入っている!!
また,記事のNewTodoの通りに
const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { await ref.add({ content, created_at: firebase.firestore.FieldValue.serverTimestamp(), }); } finally { setPending(false); } }
useStateを使ってcontentを空のstr, pendingをfalseでstateとして初期化
そして追加btnが押された時のaddの処理を書く.
asyncを噛ませてcontentを空にし,実行中ということでpendingをtrueに
tryではawaitが使われるのでこちらが先になるのか?
setContent('')が行われていないのでcontentは残っている.これが先に refにcreated_atとともに追加される
そしてtryが終わった後にpendingをfalse, NOに書きかえる
その後async前半が処理されてinput valueのcontentが空になり pendingがfalseになる.
このaddを
return ( <div> <input value = {content} onChange={e => setContent(e.target.value)} /> <button onClick={add} > Add </button> {pending && 'Pending...'} </div>
returnでinputを作り,valueには常にcontentを置き, onChangeにsetContentをしてe.target.valueをおく.
btnのonClickでaddがfireするように仕込み,
その下にはpendingがtrueの時のみ出るようにする
このComponentをAppで読み込むことによって
追加機能のあるinputとbtnが配備された.
Wesのよりかなりシンプルだ
どのcomponentでもrefは使っているので,Appで呼び出してpropsで渡そうか
しかしありえんほど簡単に
毎回firestoreをconsolelogで使用しているのもおかしいので改善策を感がてみた
config のままexportして,各自のcomponentでinitする作戦は
objのconfigをうまくconfigとしてexportできずにerror
import config from '../Config/config';
firebase.initializeApp(config);
これでうまくいきそうだが,これでもno -usedになってしまう
App側で済ますのも無理だった
これは仕方ないのかもしれない
export const firestore = firebase.initializeApp(config);
をconfig.jsに書いて
import {firestore} from '../Config/config';
をfirestore使う全てのcomponentに書くのは避けられないようだ;;;;;;
timestamp 出ないけど大まかなレイアウトは下
sort
timestampの値でsortがしたい
[1, 2,3, ] ならarr.sortで簡単だがarrのobjが必要
created_atの中身は
created_at: t nanoseconds: 964000000 seconds: 1589391378
である
これを普通に出そうとしたらめっちゃ詰まった
まぁ2020.05.21に解決して,例外処理挟んで出せるようになった, UIも書いた
ここで
React使っててなぜXSSが防げてるのかなんもわからん
dangerouslySetInnerHTMLを使うとXSSできるようになりますよ!() やれるもんならやってみて下さいよ! Add関数壊れてるわよ
おもちゃかコレェ!!!!!!!(言いたかっただけ)
動かしてなぜ動かないかわからん...
短くかける!!!と思ってここのsetTitleのところを流用してadd関数を作った
import React, { useState } from "react"; import {Col, Row,} from 'react-bootstrap'; import {Form} from 'react-bootstrap'; import {Button} from 'react-bootstrap'; import firebase from 'firebase/app'; import { firestore } from '../Config/config'; const ref = firebase.firestore().collection('writings'); const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { await ref.add({ content: content, created_at: firebase.firestore.FieldValue.serverTimestamp, }); } finally { setPending(false); } } return ( <div> <Form> <Row> <Col md = {7}> <Form.Control placeholder='write here' value = {content} onChange={e => setContent(e.target.value)} /> </Col> <Col md = {5}> <Button variant="primary" type="submit" onClick={add} > Submit </Button> </Col> </Row> </Form> {pending && 'Pending...'} </div> ) }; export default Add;
これを自分のちんちんで...じゃなくて自分で入れてbuttton押すと, 動いているように見えるが中身が入らない
エラーも出ないしわからない....
最初は動いてたもん,自分で自分のちんちん舐めたいって入れないし...
そんなに身体が柔らかくないので...(そういう問題?)
firestore追加されない問題
2020.05.30. 解決を図る.
const ref = firebase.firestore().collection('writings'); const Add = () => { const [content, setContent] = useState(''); const [pending, setPending] = useState(false); const add = async () => { setContent(''); setPending(true); try { console.log('adding'); await ref.add({ content: content, created_at: firebase.firestore.FieldValue.serverTimestamp, }); } finally { setPending(false); } }
こうしてconsole.log addingは一瞬見える.
追加中に画面が切り替わっているのだろうか?
ちんちんが追加された時はそういえばBootstrapは使っていなかった
このBtnが何か悪いのだろうか