ダボハゼのブログhttps://dabohaze.siteゆるく適当にMon, 06 Jan 2025 13:28:06 +0000jahourly1https://dabohaze.site/wp-content/uploads/2019/01/cropped-icon_site-32x32.pngダボハゼのブログhttps://dabohaze.site3232 【React】爆速でReactでChrome拡張機能を作るhttps://dabohaze.site/react-chrome-extension/Mon, 06 Jan 2025 13:25:31 +0000https://dabohaze.site/?p=4022ReactでChromeの拡張機能を作る方法です。

Chromeの拡張機能はHTML、JavaScript、CSSで作れますが、JavaScriptよりもReactの方が作りやすいので、やり方をご紹介します。

爆速でChrome拡張機能の作る もご覧いただければと思います。

「ReactでとりあえずChromeの拡張機能を作って動かす」を目的としているので、Reactの解説などは行わないのでご注意ください。

Reactのプロジェクト作成

まずはReactのプロジェクトを作成します。

npm create vite@latest

App.tsxの修正

Reactのプロジェクトが作成されたら、App.tsxを以下のように修正します。

function App() { return <button onClick={() => alert(1)}>テスト</button>;
}
export default App;

Reactアプリのビルド

yarn build or npm run buildでReactアプリをビルドします。

すると、distディレクトリが作成されます。

manifest.jsonの作成

Reactアプリとは別にディレクトリを作成します(ここではchrome-extensionとします)。

そのchrome-extensionの中にmanifest.jsonを作成し、さらにdistディレクトリ以下のファイル全てをコピーします。

chrome-extensionのディレクトリ構成とmanifest.jsonは以下のようになります。

{ "name": "Sample", "description": "Sample Extension. Show alert!", "version": "1.0.0", "manifest_version": 3, "action": { "default_popup": "index.html" }
}

Chromeで拡張機能を動かす

あとは、Chromeから作成した拡張機能を読み込み(「パッケージ化されていない拡張機能を読み込む」からchrome-extensionのディレクトリを選択)すれば拡張機能が動かせます(具体的なやり方はこちらの記事を参照)

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
dayjsの使い方をまとめてみたhttps://dabohaze.site/dayjs-how-to/Fri, 03 Jan 2025 08:48:13 +0000https://dabohaze.site/?p=4009JavaScriptのライブラリDay.js の使い方です。

format

日付のフォーマットして取得することができます。

const day = dayjs('2025-01-01 17:10:30')
day.format('YYYY-MM') // 2025-01
day.format('YYYY-MM-DD') // 2025-01-01
day.format('YYYY-MM-DD HH:mm:ss') // 2025-01-01 17:10:30
day.format('YYYY月M日D日') // 2025月1日1日

subtract

「◯日前」「◯週間前」「◯ヶ月前」「◯年前」などの日付を取得できます。

const day = dayjs('2025-01-01 17:10:30')
day.subtract(1, 'day').format('YYYY-MM-DD') // 2024-12-31
day.subtract(1, 'week').format('YYYY-MM-DD') // 2024-12-25
day.subtract(1, 'month').format('YYYY-MM-DD') // 2024-12-01
day.subtract(1, 'year').format('YYYY-MM-DD') // 2024-01-01

add

「◯日後」「◯週間後」「◯ヶ月後」「◯年後」などの日付を取得できます。

const day = dayjs('2025-01-01 17:10:30')
day.add(1, 'day').format('YYYY-MM-DD') // 2025-01-02
day.add(1, 'week').format('YYYY-MM-DD') // 2025-01-08
day.add(1, 'month').format('YYYY-MM-DD') // 2025-02-01
day.add(1, 'year').format('YYYY-MM-DD') // 2026-01-01

year、month、date

それぞれ年、月、日を取得できます。

const day = dayjs('2025-01-01 17:10:30')
day.year(); // 2025
day.month(); // 0 ※0〜11で取得されます
day.date(); // 1

startOf、endOf

月初や月末の日付を取得できます。

const day = dayjs('2025-06-15 17:10:30')
day.startOf('month').format('YYYY-MM-DD') // 2025-06-01
day.endOf('month').format('YYYY-MM-DD') // 2025-06-
day.startOf('year').format('YYYY-MM-DD') // 2025-01-01
day.endOf('year').format('YYYY-MM-DD') // 2025-12-31

isBefore、isAfter、isSame

日付の比較ができます。

const day1 = dayjs('2025-01-01 00:00:00')
const day2 = dayjs('2025-01-02 00:00:00')
const day3 = dayjs('2025-01-03 00:00:00')
day1.isBefore(day2) // true
day2.isAfter(day3) // false
day3.isSame(day1) // false

第二引数で日付のどの単位までで比較するかを指定できます。

const day1 = dayjs('2025-01-01 00:00:00')
const day2 = dayjs('2025-01-01 00:01:00')
console.log(day1.isSame(day2, 'year')) // true
console.log(day1.isSame(day2, 'month')) // true
console.log(day1.isSame(day2, 'date')) // true
console.log(day1.isSame(day2, 'hour')) // true
console.log(day1.isSame(day2, 'minute')) // false
console.log(day1.isSame(day2, 'second')) // false

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
【JS】関数の引数はオブジェクトで渡したいhttps://dabohaze.site/javascript-function-argument-object/Mon, 30 Dec 2024 09:52:22 +0000https://dabohaze.site/?p=4005タイトル通りですが…

普通、JavaScript(TypeScript)で関数に引数を渡す場合、以下のようにします。

const hogeFunc = (hogeName: string, hogeValue: number, hogeFlag: boolean) => { // 処理
}
// 関数呼び出し
hogeFUnc('hoge', 55, true)

引数の数が少なければ、これでもいいかもしれません。

ただ、引数の数がもっと増えた場合や、デフォルト引数を使用する場合に問題になります。

例えば以下のような場合です。

const hogeFunc = ( hogeName: string, hogeValue: number, hogeFlag1?: boolean = false, hogeFlag2?: boolean = false, hogeFlag3?: boolean= false,
) => // 処理
};
hogeFunc("test", 12345, false, false, true)

hogeFlag1、hogeFlag2、hogeFlag3はオプショナル引数なので、省略できます。

でも、「hogeFlag3にtrueを渡したい。hogeFlag1とhogeFlag2はデフォルト値でOK」という場合はhogeFlag1とhogeFlag2にfalseを指定する必要があります。

必要な引数は3つだけなのに5つ全部書く必要があり面倒です。

また、引数の順番も気にする必要があり、上記のように同じ型の引数が並んでいると間違いも起こりやすいです。

上記をオブジェクトで渡すようにすると以下のようになります。

const hogeFunc = ({ hogeName, hogeValue, hogeFlag1 = false, hogeFlag2 = false, hogeFlag3 = false,
}: { hogeName: string; hogeValue: number; hogeFlag1?: boolean; hogeFlag2?: boolean; hogeFlag3?: boolean;
}) => { // 処理
}; hogeFunc({hogeName: "test", hogeValue: 12345, hogeFlag3: true})

必要な引数だけの指定でよく、オブジェクトのキーのおかげで「このtrueは何のフラグだ?」となることも減りそうです(サンプルなのでhogeFlagという名前ですが、実際にはわかりやすい名前で命名されるはず)

また、引数の順番も気にする必要がなくなります。

個人的には引数が3つまではOK、4つ以上はオブジェクト形式かなと思っています(boolean型のフラグがある場合は特に)

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
Chromeでプラグインなしで画面全体のスクリーンショットを取得する方法https://dabohaze.site/google-chrome-developer-tool-screenshot/Sun, 06 Oct 2024 12:39:05 +0000https://dabohaze.site/?p=3983Google Chromeでデベロッパーツールを使用して、プラグインなしで画面全体のスクリーンショットを取得する方法です。

プラグイン使ったほうが楽ですが、セキュリティの関係でプラグイン使用不可の場合もあると思うので、そんなときに使えます。

まず、Chromeでデベロッパーツールを開きます。

Screenshot

Macの場合はキーボードでCmd + Shift + Pを押します。

すると、以下のようなウィンドウが表示されます。

表示されたウィンドウで「スクリーン」と入力すると、以下のようにコマンドが絞り込まれて表示されるので、「フルサイズのスクリーンショットをキャプチャ」をクリックすれば、全画面のスクリーンショットを取得できます!

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
【React】「React has detected a change in the order of Hooks called by〜」の対処法https://dabohaze.site/react-hooks-top-level/Mon, 26 Aug 2024 06:52:42 +0000https://dabohaze.site/?p=3970エラー概要

Reactで「React has detected a change in the order of Hooks called by〜 . This will lead to bugs and errors if not fixed.」のエラーが発生した場合の対処法です。

上記エラーは、useStateなどのHooksが呼び出される順序が変わったときに発生するそうです。

Reactでは、Hooksはトップレベルで呼び出す必要があります。

フックをループや条件分岐、あるいはネストされた関数内で呼び出してはいけません。代わりに、あなたの React の関数のトップレベルでのみ、あらゆる早期 return 文よりも前の場所で呼び出してください。これを守ることで、コンポーネントがレンダーされる際に毎回同じ順番で呼び出されるということが保証されます。これが、複数回 useState や useEffect が呼び出された場合でも React がフックの状態を正しく保持するための仕組みです

参考:https://ja.legacy.reactjs.org/docs/hooks-rules.html

そのため、if文や下記のような早期return文の後にHooksを書くとHooksの順序が変わってしまいエラーが発生します。

import { useEffect, useState } from "react";
const Sample = ({ count }: { count: number }) => { const [flag1, setFlag1] = useState(true); if (count === 0) { return <></>; } const [flag2, setFlag2] = useState(true); return <>{count}</>;
};
export default Sample;

対処法その1:Hooksは関数のトップレベル、早期return文より前に書く

Hooksは条件分岐内や早期return文の後ではなく、トップレベルに書く必要があります。

下記のように、早期return文より前にHooksを書けばエラーは発生しなくなります。

"use state";
import { useEffect, useState } from "react";
const Sample = ({ count }: { count: number }) => { const [flag1, setFlag1] = useState(true); const [flag2, setFlag2] = useState(true); if (count === 0) { return <></>; } return <>{count}</>;
};
export default Sample;

対処法その2:コンポーネントとして切り出す

下記のように、コンポーネントとして切り出した場合もエラーは発生しません。

import { useEffect, useState } from "react";
const Parent = ({ count }: { count: number }) => { const [flag1, setFlag1] = useState(true); if (count === 0) { return <></>; } return <Children count={count} />;
};
const Children = ({ count }: { count: number }) => { const [flag2, setFlag2] = useState(true); return <>{count}</>;
};
export default Parent;

そもそもの話

VSCodeでeslintの設定されていれば、コード書いているときに以下のようにエラーを表示してくれるので気付ける。

React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
Chromeのデベロッパーツールの便利な使い方https://dabohaze.site/chrome-developer-tool/Mon, 22 Jul 2024 09:32:45 +0000https://dabohaze.site/?p=3897フロントエンド開発をしていると、ブラウザのデベロッパーツールをよく使います。

Chromeのデベロッパーツールで知っておくと便利な使い方をご紹介します。

日本語化

デベロッパーツールを開き、右上の歯車 > 言語 で日本語を選択し、デベロッパーツールを開き直すと日本語になります。

画面遷移してもconsole.logを残す

変数や条件分岐でconsole.logを出して検証するということはよくあると思いますが、画面遷移をすると消えてしまいます。

コンソールタブ上部にある「ログを保持」をチェックをすると画面遷移してもログが消えずに残ります。

画面遷移してもネットワークのログを保持

ネットワークタブで、APIのリクエストやレスポンスを確認したいこともよくあると思いますが、これも画面遷移をすると消えてしまいます。

ネットワークタブ上部にある、「ログを保持」をチェックすると画面遷移してもログが消えずに残ります。

ネットワークタブの行を大きく表示

ネットワークタブのログはデフォルトだと以下のように表示されます。

Name列にはAPI名やファイル名が表示されますが、エンドポイントは行を選択してヘッダーを見ないとわかりません。

ネットワークタブ上部にある、「大きなリクエスト行」をタップすると、エンドポイントも表示されるようになります。

低速ネットワークでの確認

低速なネットワークの状態で、どのような挙動になるか確認したいこともあると思います。

ネットワークタブで、「スロットリングなし」をクリックし、「高速 3G」や「低速 3G」を選択すると低速なネットワークでWebアプリの挙動を確認できます。

ローカルストレージ、セッションストレージ、Cookieの確認

ローカルストレージ、セッションストレージ、Cookieは、アプリケーションタブから確認できます。

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
iPhoneのSafariで開いているページのデベロッパーツールを開く方法https://dabohaze.site/iphone-safari-developer-tool/Tue, 30 Apr 2024 00:36:50 +0000https://dabohaze.site/?p=3923MacでSafariを使用している場合、Option + Command + i でデベロッパーツールを開き、ネットワークタブやコンソールタブで検証することができます。

ただ、iPhoneのSafariでは単体ではデベロッパーツールを使うことはできません。

iPhoneとMacを使用して、「iPhoneのSafariで開いているページのデベロッパーツールをMacで開く方法」をご紹介します。

やり方

1. MacでSafariを起動します

2. iPhoneとMacをケーブルで接続します

3. iPhoneのSafariを再起動します

4. iPhoneのSafariで、デベロッパーツールを使用したいページを開きます

5. MacのSafariのメニューバーの「開発」をクリックします

6. 以下のような表示になっているはずなので、iPhoneにカーソルを乗せます

7. デベロッパーツールを使用したいページ(タブ)をクリックします

8. iPhoneのSafariで開いているページのデベロッパーツールが起動します!

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村


]]>
SWRで取得したdataをReact Hook FormのdefaultValuesにセットするhttps://dabohaze.site/swr-react-hook-form-default-value/Sun, 07 Apr 2024 07:53:02 +0000https://dabohaze.site/?p=3919SWRで取得したdataを、React Hook Form(以降はRHF)のdefaultValuesにセットしたいことがあると思います。
以下のような感じです。

"use client";
import { useForm } from "react-hook-form";
import useSWR from "swr";
export default function Home() { const fetcher = () => fetch("/user/1").then((res) => res.json()); const { data, isLoading } = useSWR( "/user/1", fetcher ); const { register } = useForm({ defaultValues: { name: data?.name, }, }); return <input {...register("name")} />;
}

しかし、このやり方だとdefaultValuesにうまくセットされません。
なぜなら、dataはフェッチしたデータが入るまではundefinedとなっているため、defaultValuesにはundefinedがセットされてしまうためです。
データがフェッチされても、defaultValuesは上書きされないんですね。

この現象は、useEffectを使用すれば回避できます。

"use client";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import useSWR from "swr";
export default function Home() { const fetcher = () => fetch("/user/1").then((res) => res.json()); const { data, isLoading } = useSWR( "/user/1", fetcher ); const { register, reset } = useForm(); useEffect(() => { if (isLoading) return; reset({ name: data?.name }); }, [data, isLoading, reset]); return <input {...register("name")} />;
}

useEffectの依存配列にSWRのdataを指定しています。
SWRでデータがフェッチできたタイミングでuseEffectが実行され、RHKのresetで初期値をセットされます。

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
【React】RHKのresetで勘違いしていたことhttps://dabohaze.site/react-hook-form-reset-empty/Sun, 22 Oct 2023 06:52:41 +0000https://dabohaze.site/?p=3904React Hook Formのresetは「Formを空にする」という理解でいましたが勘違いしていました。

"use client";
import { useForm, SubmitHandler } from "react-hook-form";
export default function Home() { const { register, reset } = useForm({ defaultValues: { hoge: "test", }, }); return ( <> <input {...register("hoge")} /> <button onClick={() => { reset(); }} > リセット </button> </> );
}

上記は、defaultValuesでhogeの初期値に「test」を設定しています。
hogeの値を変更後、リセットボタンを押下するとhogeの値は空ではなく「test」になりました。

値を空にするにはreset({ hoge: "" })とするか、setValueを使用してsetValue("hoge", "")とすればできました。

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>
【React】SWRで定期的に再検証する方法https://dabohaze.site/swr-refreshinterval/Mon, 18 Sep 2023 12:22:05 +0000https://dabohaze.site/?p=3899SWRで定期的に再検証する方法です。

refreshIntervalを使用すると実現できます。

"use client";
import { useEffect, useState } from "react";
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((r) => r.json());
export default function Home() { const [status, setStatus] = useState(false); const { data } = useSWR("http://localhost:3100/api/users", fetcher, { refreshInterval: !status ? 5000 : 0, }); useEffect(() => { if (data.status === "OK") { setStatus(true); } }, [data]); return <>〜省略〜</>;
}

上記の例では、5秒おき(5000ミリ秒)に再検証するようにしています。

refreshIntervalは0を指定すると自動再検証がストップするので、再検証したレスポンスをもとに再検証を止めるようにしています。

setIntervalなどを使って自作する必要がないので便利です。

IT技術ブログ
↓↓「にほんブログ村」のランキングに参加しています。少しでも面白い、参考になったとか思われたらポチッとしていただけると嬉しいです!

にほんブログ村 IT技術ブログへ

にほんブログ村

]]>