LL
[Javascript]
const function = () => {
for (const doc in docs) {
if (){
return
}
}
}
for 文から脱出したい時に間違って、return としていて、function から出てしまっていた。
for 文を終わらせたい時は break
、for 文のループをスキップしたいときは continue
を使う。
[Javascript]
async のエラーハンドリング。
asyncをつけると 「Promise」を返してくれるので、呼び出し側に catch とか付ければ見た目スッキリする。
// 以前
const func = async () => {
let url
try {
~~~~~~
} catch (err) {
~~~~~~
}
}
func()
// スッキリ
const func = async () => {
}
func()
.then()
.catch()
[HTML]
input type="number"
で、 step=1
を指定すると、整数のみの validation が設定される。
<input
type="number"
step="1"
/>
[Typescript]
input type="number"
としても、型は number にならない。そのため、e.target.value
は string型となってしまう。この場合、 Number()で括ることで、number型にする。
const num = Number(e.target.value)
[Typescript]
オブジェクトの場合、オプショナルは省略可能、unionは省略不可。
type User {
name?: string;
}
type User {
name = string | undefined;
}
後者の場合、関数の中などで name=undefined
と明示する必要がある
[Javascript]
オブジェクトのキーを変数にしたい場合 [] をつける
{key: value}
とすると key: "太郎"
となってしまう。
const key = name
const value = "太郎"
const obj = { [key]: value }
console.log(obj) // { name: "太郎" }
[React]
// これしか知らなかった。
<h1>{user.name ? username : "No name"}</h1>
// user が true なら、user.nameを返す。
<h1>{user && user.name}</h1>
// さらにスッキリ
<h1>{user?.name}</h1>
// user.name が true なら、user.nameを返して、falseなら || の隣を返す。超便利。
<h1>{user.name || "No name"}</h1>
引用:
javascriptでは空文字や数字の0はfalse評価されてしまう......
知らなかった。
参考:
[React]
<input
type="text"
name="title"
value={cardTitle}
onChange={(e)=>setCardTitle(e.target.value)}
/>
input フォームで出たエラー。
入力内容を onChangeで拾って、setStateで value にセットしていた。「uncontrolled から controlled に変わっちゃってるよ」というwarning.
下記のように初期値を与えたら直った。
// before
const [cardTitle, setCardTitle] = useState()
// after
const [cardTitle, setCardTitle] = useState('')
初期値を与えていなかったので、 <input value={undefined}> となってしまって(uncontrolled)、後から setState の値をぶち込もうとして(controlled)、warningが出たのかも?
[React]
svg は react-svg-loader を活用。
[Javascript]
posts(配列) の真偽値判定の時、posts = [] (配列が空)でも true となってしまうので、posts.length
が 0かどうかで判定する。
[Javascript]
Object.keys(arr[0]).map(key => {
if (key == "tableId") return
console.log(key)
})
}
map
で スキップしたい時に continue
は使えなかった。 省きたい条件をif文で書いて return
させれば解決した。
[React]
内容:button の onClick時、setState させてるにもかかわらず、stateが更新されなかった。
原因:useEffectで毎回初期値をsetStateしていたんだけど、useEffectの第二引数[]を指定していなくて、毎回useEffect されていた模様。
// before
useEffect(()=> {
setPosts(props.posts)
})
// after
useEffect(()=> {
setPosts(props.posts)
},[])
🔥[React]
内容:props で持ってきたデータを state 管理&mapで回したいんだけど、よく分からず
原因:不明🤮🤮🤮🤮🤮🤮🤮
// これはイケる。けど、stateで管理したい(postsを追加・削除するので)
const CardList = (props) => {
const posts = props.posts
return (
<div>
{posts && posts.map()}
</div>
)
}
// これはダメ。初期値が入らない。
const CardList = (props) => {
[posts, setPosts] = useState(props.posts)
return (
<div>
{posts && posts.map()}
</div>
)
}
// これもだめ。
const CardList = (props) => {
[posts, setPosts] = useState()
useEffect(()=> {
setPosts(props.posts)
},[])
return (
<div>
{posts && posts.map()}
</div>
)
}
[Git]
ブランチの削除の仕方
// ローカル側のブランチ削除
git branch --delete [branch name]
// -d でも可
git branch -d [branch name]
// リモート側のブランチ削除
git push origin :[branch name]
[Nextjs][Typescript]
type Props = {
posts: Posts[];
user: user;
}
// NextPage に generics で Props型を指定
const Page: NextPage<Props> = (props) => {
~~
~~
}
// getStaticProps の 返り値の型をチェックできる
export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
~~
~~
return {
props: {
posts,
user,
}
}
}
[React][Typescript]
関数コンポーネント(Function Component)の props の型の指定方法
type Props = {
body: string;
}
// React.FC を指定して、 generics をつける
const Post: React.FC<Props> = (body) => {
}
[Typescript]
// rows, cols は number なので、下記はダメ(stringになっている)
<textarea
rows="4"
cols="40"
/>
// {数値} としてあげる
<textarea
rows={4}
cols={40}
/>
[React]
Escキーで Modalを閉じるケース
-
document.addEventListener
で keydownイベントが発生するときに通知を受け取るkeyPress
listener を登録 -
useCallback
で Escapeキーを押した時の関数をメモ化(キャッシュ的な) - Modal のアンマウント時に、登録したリスナーを削除(
removeEventListener
) - useEffectの第二引数に
keyPress
を登録しておくことで、Modalアンマウント時のclean up
を呼べる - useCallbackの第二引数に
setShowModal, showModal
を指定することで、これらの変数が変わるごとに再実行(setShowModalを記載する理由がよく分からん)
const keyPress = useCallback(
e => {
if (e.key === 'Escape ' && showModal) {
setShowModal(false)
}
},
[setShowModal, showModal] // ここの変数が変わったら再実行
);
useEffect(() => {
document.addEventListner('keydown', keyPress)
return () => document.removeEventListener('keydown', keyPress) // アンマウント時の処理
},[keyPress]) // ここの変数が変わったら再実行
参考:https://sbfl.net/blog/2019/11/12/react-hooks-introduction/
参考:https://www.youtube.com/watch?v=d3aI1Dt0Z50
[CSS]
flex-box使用時、カードを2列表記から1列表記にしようと思って flex-wrap: nowrap
を指定したら、それぞれのカードが詰まって配置されてしまった(width: 40%
的なものが無視された)。
正しくは、flex-wrap: wrap
を指定して、width: 100%
とする。
[Firestore]
Firestore の Timestamp データを基に、dayjs.extend(relativeTime)
を使って、投稿時間と現在時刻の差を出したかった。
Timestampデータは {nanoseconds: 431000000, seconds: 1612952177}
といったオブジェクトであり、dayjsの引数は JS の Date型 である必要があった。
そのため、toDate()
を使うことで解決
const date = createdAt.toDate() // createdAt は Firestore の Timestamp
~~~
~~~
<time dateTime={date}>
{dayjs(date).fromNow()}
</time>
[Firestore]
collectionGroup で orderBy
を指定したところ、エラー。
firebase console で index を設定する必要があった。エラーコード内のリンクをクリックすると、必要なインデックスを提案してくれる。
参考:https://qiita.com/yoshihide_tsukamoto/items/ad37dab65d4587f8be6e
[Firestore]
配列に要素を追加したかった。{merge: true}
では上書きされるため、arrayUnion
を使う。
// 上書きされるケース
firebase.firestore().collection("companies").doc(symbol)
.set({events: eventName}, {merge: true});
// 配列に追加
firebase.firestore().collection("companies").doc(symbol)
.update({events: firebase.firestore.FieldValue.arrayUnion(eventName) });
[HTML]
button の onClick を使って関数を実行すると、ページ遷移される。これは、button のtype が デフォルトで submit
であったため。 button
属性にすれば、ページ遷移されない。
// レンダリングされる(デフォルトで type="submit"のため)
<button onClick={()=>func()} >完了</button>
// レンダリングされない
<button type="button" onClick={()=>func()} >完了</button>
// func()の中で、 e.preventDefault() としても、ページ遷移を防げる。
[GAS]
Google App Script を使って、Google Adsense の結果を LINE に通知しようと思った時に、message: may not be empty
エラーが出た。message にはきちんとデータが入っていたが...🤔
function main() {
var text = lastMonth + "月のadsense成果発表です🎉\n"
+ "\nページビュー数\t" + report[0][0] + "回"
+ "\nCTR:クリック率\t" + report[0][1]*100 + "%"
+ "\n\n💰今月の収益💰\t" + report[0][2] + "円"
SendToLine(text);
}
function SendToLine(message) {
var token = "XXXXXXXXXXXXXXXXXXXXXXXXX";
var op =
{
"method": "post",
"Content-Type": "application/x-www-form-urlencoded",
"payload": "message=" + message,
"headers": {"Authorization": "Bearer " + token}
};
var res = UrlFetchApp.fetch("https://notify-api.line.me/api/notify", op);
}
原因は、CTRクリック率を示すところで、「半角の%」が入っていたため。
[Firestore]
セキュリティルールのテスト
// 1. Packege json に下記を記載
"test": "firebase emulators:exec --only firestore 'jest'"
// 2. 実行
npm run test
[Firestore]
セキュリティールールで急にエラー。
match の インデントに騙されて、無駄なブラケットがついていた。
このせいで、エラーになって動かないだけでなく、動くけどテスト結果がおかしい(FailsがSucceedsしたり)ことになった。
Firestoreのセキュリティールールのテスト中、急に結果がおかしくなった。認証(isAuthenticated)が全てFailsに変わった。
セキュリティールールの中で、「tags は無くてもいい or tagsはマップ型」とすべきところの記述がおかしかった。
// ! の位置がおかしい
&& ((!'tags' in request.resource.data) || (request.resource.data.tags is map))
// 正しくはこっち
&& (!('tags' in request.resource.data) || (request.resource.data.tags is map))
[firestore]
オブジェクトは map, 配列は list
// オブジェクト
&& (!('tags' in request.resource.data) || (request.resource.data.tags is map))
// 配列
&& (!('Etags' in request.resource.data) || (request.resource.data.tags is list))
[Firestore]
下記のエラーがでた。request.resouce.data.name の data をつけ忘れてた。
FirebaseError: 7 PERMISSION_DENIED:
Property name is undefined on object. for 'create' @ L117
// NG
&& request.resource.name is string
// OK
&& request.resource.data.name is string
[React]
mapで配列を展開した時に要素が表示されなかった。() で囲むべきところを {} で囲んでいた。
// NG
{members.map((member, i) => { // 👈
<div>{member.name}</div>
})}
// OK
{members.map((member, i) => (
<div>{member.name}</div>
))}
[Firebase auth]
本番環境で firebase auth の サインインメソッドが使えなかった。
👉 firebase console => auth で、承認済みドメインに追加すればOK。
[React]
map で展開した input要素 を delete した時に、DOM上でのデータ反映がうまくいかなかった。
原因:
key を todo-${i}
のように、インデックス展開していたため。
要素が並び変わる可能性がある場合、インデックスをkeyにすると不都合が起きるとのこと(公式サイトより)。
対策:
一意なキーを振るために、 key = Date.now() と設定した。
Firebase cloud functions
内容:エラー探しに時間を要した。
- エラー箇所が見つけられなかった(575行目???ってなった)
- 名付けた覚えのない _b という変数が見つけられなかった
結果:
typescript のコンパイル後のファイル(出力先 lib 以下の js ファイル)を見れば、正しいエラー箇所がわかる
Firebase extensions (stripe/firestore-stripe-payments@0.2.2)
内容:
Stripe の拡張機能のアップデート後、webhook エラー発生。
原因:
- 今回から Secret Manager に対応されたが、そこで設定するトークンをミスった(dev と prod のトークンを逆にしていた)
- webhook の指定URLがちゃっかり変わっていたことに気がつかなかった。
// before
https://asia-northeast1-XXXXX.cloudfunctions.net/ext-firestore-stripe-🔥[subscriptions]🔥-handleWebhookEvents
// after
https://asia-northeast1-XXXXX.cloudfunctions.net/ext-firestore-stripe-🔥[payments]🔥-handleWebhookEvents