ソフトウェア開発」カテゴリーアーカイブ

甦れ!アンパンマン

上の子が小さい頃に買ったアンパンマンのおもちゃがずっとしまってあったのですが、次女が最近アンパンマンを好きになっているので取り出してみました。

セガフェイブ(SEGA FAVE) アンパンマン かまどでぷく~ ジャムおじさんのやきたてパン工場
https://amzn.to/4gfe6cK

今はすでに販売中止になっていて、後継のおもちゃが出ているようですね。

喋らない

電源をONにしてみても、なんの反応もありません。
電池を見てみると。。。

やはり緑錆にやられてしまっていました。。。

うーん、遊んでなかったおもちゃあるあるですね。。。
これどうしたものなんだろう?と調べてみると、緑錆にはKURE5-56ではなくKURE2-26なるものがあると!

KURE(呉工業) 2-26 180ml 電気装置用防錆・接点復活剤 1020

買いました

緑錆に効くというよりは、電源などの接点を復活させることができるとのことで、綿棒使ってお掃除してみました。

続・喋らない

それでも音は鳴りませんでした。

うーん、接点がだめだったのか、それとも接点以外の問題があるのか・・・
とりあえず、中を開けてみることにします

ちょっと画像からは分かりづらいですが、下部の電源から伸びている金属が緑錆でやられていて。。。あれ、右下何もつながっていない??

そして、一本、配線がプラプラしている。。。

つまり、緑錆などで傷んでしまって配線が切れてしまったということなんですかね?
これを接合してあげれば復活しそうな気がしてきます。

接合といえばはんだごてですよ

はんだごて

買いました。

Lesimoll はんだごて ハンダゴテ 14-in-1はんだごてセット 溶接工具 精密半田ごて 電気ハンダゴテ 60W/110V 温度調節可能(200~480℃) 5つ無酸素銅こて先 50g高純度はんだ ON/OFFスイッチ付き 半田吸取器 日本語取扱説明書付き...

比較的お値段が手頃なものを。。。
なんか色々と付いてきていますが、例のごとく使いこなせる気はしません。
シンプルに接合できればよいと。

復活!!

「焼き立て!かまどでパン屋さん!」とアンパンマンが喋ってくれました!

喜びのあまり妻に経緯を説明したら、「買ったほうが安く上がったのでは・・・?」など冷たい言葉を浴びせかけられましたが、それでは面白くないじゃないですか。

一体、ハンダゴテなんていつ以来だろう。。。もはや思い出すことができませんね。
大学時代に溶接ならガスもアークもやりましたが。。。

いやー、楽しかったです

v0を触ってみた

Vercel社が提供しているv0というサービスを触ってみました

v0はClaudeCodeとはちょっと立ち位置が違う。
プロンプトを用いてアプリケーションを作ってくれるといえばそうなのだが、ClaudeCodeが開発者向きで、生成したコードを見ることが想定されている用に感じる。

それに対してv0は非エンジニアやちょっとしたプロトタイプを作成したい際に、アプリケーションを作ってデプロイまでしてしまう。
ClaudeのArtifactのようにも思えるが、Supabaseなどと連携してVercelの環境で動かすことができてしまう。

今回、こんなプロンプトでクイズアプリケーションを作ってもらった

早押しクイズを提供するサイトを作ってください。
問題出題者はクイズとしてクイズの名前、問題数、カテゴリを登録。
さらに問題とその答えの選択肢、答えと回答時間を設定することが可能です。
クイズをオープンすると、回答者を待つ状態になり、クイズの回答者が参加することが可能になります。
出題者がスタートさせると、回答者の受付は終了し、各回答者のブラウザにクイズの問題と選択肢が提供され、回答を選択することができます。
全員の回答が出揃ったらその問題の答えが出て、正解・不正解と回答の時間によって得点が割り当てられます。
一定時間経つと次の問題が始まります。
最後の問題が終わった段階で、各回答者の得点が表示され、順位が決定します。

結果からすると、思った以上に考えられたものが出来上がったと思う。もちろん、作ってもらうものの参考とするアプリケーション・サービスがそれなりにあるはずで、そういったニーズのものであれば「こういう機能がついている」というセオリーも学びやすいのだろう。

Supabaseと組み合わせることで、ユーザ認証・DBを含めたアプリケーションが出来上がってしまった。
詳しくテストまではできていないのだけど、簡単なものであればそのまま使えるんじゃないかな?と思えてしまった。

技術スタック

v0が生成してくれるコードの技術スタックはVercel提供だけあってNext.jsになる。
Tailwind.cssなどNext.jsを用いる場合に、モダンとされている組み合わせを提供してくれるので、それに関してはこだわりがなければ良さそう。

ちなみに今回作成したUIはpackage.jsonを見るとradix-uiが主に使われているよう。
フロントエンドは不勉強すぎて、radix-uiというものを初めてしった。

Radix UI

Radix-UIは機能のみを提供してスタイルは提供せず自由にカスタマイズ可能というコンセプトのようで、プロジェクトとしては、Radix-UI+TailwindCSSなんですね。

作るものの技術スタックを自分で選びたい。もしくは、すでに決まってしまっている場合には全く使えないものになってしまいそう。
このあたりはプロンプトの指示でどうにでもなるのかもしれない

料金プラン

料金プランはFreeの上はPremiumになっていて、最近多くなってきた月$20というところ。
Freeプランだと$5分が毎月割り当てられる

今回、試しに作ってみたクイズアプリケーション。
中身的にはいい感じだが、これを作るのに・・・

だいたい$3くらいですね。
Claudeへ課金していることを考えると、安く感じてしまうけれど、Supabaseの料金もこれにかかってくるんですよね。

とはいえ、コードはダウンロードして取得したりGithubにそのままコードをPushできるので、Supabaseへの接続部分を変えてしまえば自前で環境は構築できるんじゃないかな・・・。
そのあたりが実は面倒だと、使うのはちょっとためらってしまいそうですね。

感想

どの程度のものが出来上がるかな?と軽い気持ちで試してみたけれど、それなりのものが出来上がってしまってびっくりしている。

恐ろしい子。。。

プロジェクトとしては今回のようにプロンプト初めてもいいし、Githubのリポジトリから持ってくることもできる

ここで見てみると、TemplateにFrameworkの指定をすることができる。
現時点での選択肢としてはこのようだ

機能やコードに対しての品質的なところまではまだ見切れていないので、CloneしてきてClaudeCodeに評価させるなりしたり、実際にPublishしたりして動かしてみたいですね。

また、Supabaseなど今まで自分が知らなかったサービスやFrameworkを知る機会としてもこういうものが利用できると改めて思いました。

ちょっと楽しくなってきたぞ!

Shokzの調子が悪い。。

2年半ほど愛用しているShokzのOpenRunですがついに動きがおかしく・・・

購入したのが2023年なので保証はすでに切れてしまっている。。

ただ、全然動かないというわけではなく、おそらく電源ボタンの接触周りなのではないかという予想。

shokzの場合、電源ボタンと音量の+が同じボタンなのですが、その両方がうまく聞かないんですよね。
そしてペアリングモードは電源の長押しなのでその周りでは。。と。

ただ、アクションボタンも反応してくれないのですよね。
昨日までは、大丈夫だったと思うのですが。。。

このボタン周りをゴムっぽい生地で囲んでいて、それが耐久力的に持ってなくて破れています。
このゴムが耐水性を兼ねているのだとしたら、ここから汗などが入り込んでおかしくなってしまったのでしょうか。。。

ランニング中はもちろんのこと仕事でも使っているのでこれがなくなるのは非常に困る。
最悪仕事は有線イヤホンでもなんとかなるけれどランニングは有線には戻りたくない!!

とりあえず、商品の保証期限は切れているものの修理ができるか。そして修理のお値段を知りたいので問い合わせをしてみることに

https://jp.help.shokz.com/s

買い替えになってしまうのかなぁ。
カバーの耐久力はもう少しなんとかしてほしいところですね

家庭菜園を管理できるようになりたい

ちょこちょこと報告をしていますが、家庭菜園をしています。

ただ、日々の忙しさや雑草の多さに油断をするとすぐに放置してしまうんですよね。
しかも、作ったものが家で喜んで食べてもらえるかというと、必ずしもそうではありません。
自家栽培の野菜たちは、売っているプロが作ったものよりも美味しいという成功ばかりではありません。

傷がついたり虫食いだったり、スジが多くて硬かったり。。。
収穫のタイミングの難しいものもあったりもします。

大変な割に、そういう意味では報われず、育て始めた当初から徐々にモチベーションは下降していったりします。

せめて、育て方や内容を効率的に管理し、なおかつ必要な時期に必要なタイミングで肥料などをやるなど、美味しく育てる仕組みがほしいです。

開発者らしく、そういうものを作ったらいいじゃん!って思うことはや◯年。
なかなか重い腰は上がらないものです。

ただ、AIなど環境が揃ってきて効率的にものを作る事ができる状態になっている今、動かないのはただの怠慢だろうなと思い、要件の詰めをClaude君と会話し始めました。

日の目を見ることはだいぶ先になるんじゃないかとは思うのですが、まずは動き出してみようと。

Cursorをインストールしてみた

AI開発エディタとしては有名どころの一つであるCursor。
これまで名前は知っているものの、Claude codeで遊んでいたので使ったことはありませんでした。

とはいえ、触ってみないのもな?と思いインストールしてみました

https://www.cursor.com/ja

インストーラ自体は公式サイトから落としてきて実行するだけ。
特に選択肢も対してあるわけでもないので割愛します。

初回起動時にはログイン方法を選択。
後々、Githubとは接続するだろうということで、Githubアカウント連携でのログインを選択、関連付けました

唐突に何かをVSCodeからImportさせようとするCursor。
せめてなにか書けよ・・・。
おそらくは、外観の設定周りなのではないかと推察してとりあえずImportするか。。

Importを選択してから、何をImportしようとしているかの選択が出てくる。
このUXは本当に大丈夫なのだろうかと心配になってくる

テーマ設定画面となった。
Pick your vibeってのがvibe codingとかけているのか、ちょこっとくすっと来た

分かりづらいが、key bind を VSCode, Vim, Emacs, Sublime Textから選択できる。
Sublime Textとか懐かしい。

Emacsを選択しても面白いのかもしれないけれど、Emacs使っていたの本当に数年なので正直覚えておらず、やはりVSCodeを選択させてもらう

コードベースからの学習を許可するか聞いてくる。
ここは迷いどころではあるけれど、少なくとも個人PCにいれている内容であれば別に構わないんだけどなぁと言うのが正直なところ。
色々迷うところではあるけれど、初期段階ではチェックボックスをOnにしないと先に進めない。

Autoでもいいかな?と思ったけれど、Japaneseを選択させてもらおう・・・

ようやく設定が終わり、Cursorが使えるようになったかな?

設定周りでいうと、このRulesがおそらく肝になってくるなじゃないかな?と思うので、ここからはもう少し調べながらやってみようかな。

CloudとのVPNに関してのメモ

Microsoft Azureの一番初歩的な資格であるAZ-900を以前勉強していたのですが、結局試験を受けていません。
そもそも受けようと思ったのも、たまたま無料のバウチャーをいただいたからという、どうしょうもない動機だったのですが、最近Azure上にアプリを作るという案件に関わっているので、この際取ってしまおうと思っています
(自分がAzureを触ることはあまりなさそうですが。。。)

Udemyで練習問題を解いているのですが、VPN周りで用語がAWSとこんがらがってミスってしまったので、名称含めて一度整理しようと思います。

Azure

AzureとオンプレミスなどとをVPNで接続する方法としては下記となる

P2S(Point-to-Site) VPN

Azureのネットワークとクライアント端末とをVPN接続する目的で利用される。
使われるサービスとしては、Azure側にVPNGatewayを構成する必要がある。

気をつけるのが、このVPNGatewayと書かれている箇所と仮想ネットワークゲートウェイと書かれている場所と二通りあって、同じものを指している点。
資格試験の問題文としてどちらが出るかわからない。。。
こういうのまじでやめてほしい。

S2S(Site-to-Site) VPN

Azureのネットワークとオンプレミス側のネットワークをVPN接続する。
使われるサービスとしては、Azure側にVPNGatewayは必要で、追加でLocalNetworkGatewayが必要になる。

このLocalNetworkGatewayがオンプレ側のVPNデバイス(ルーター)と接続されるとのこと。

詳しくはこのあたりが図も書かれていてわかりやすかった

Azure と接続する 3 つの方法
https://www.rworks.jp/cloud/azure/azure-column/azure-entry/22077/

AWS

AWSの場合も基本的には似たようなVPNの仕組みがあるけれど、サービス名が違っている。

AWS側ではVirtualPrivateGatewayもしくはTransitGatewayがVPNの受けてとして登場する。

そして、AWSでVPNの紹介のときによく上記のような絵が出てくるけれど、CustomerGatewayはAWS上に構築するんですよね。
AWS上に構築するけれど、”オンプレミス側のカスタマーゲートウェイデバイスを表す”みたいな表現方法をされるので上記のような図になってしまうんだろうけれど、結局のところAzureでいうところのLocalNetworkGatewayがこれに当たるのだと理解した。

GCP

https://cloud.google.com/network-connectivity/docs/vpn/concepts/overview?hl=ja

こちらを見ると、HA VPNとClassic VPNの2種類があるようですが、Classicは非推奨になっていくようなので実質的にはHA VPNのみ。

使うサービスとしてはHA VPN gatewayのようだけれど、図にはCloud Routerも出てきていてしっかりと理解は出来ていない。

とりあえず、GCPに関しては現時点では予定はないからいいか。。。

最後に

この辺の資格試験で問題となるのは、用語の統一性がないんですよね。
AWSやAzureで似たような機能を異なるサービス名で提供されていたり、同一のクラウドの中でも呼び名が時期によって異なっていたりして安定していません。

そして、設問の選択肢としてそれらが入り混じって出題されると一気にパンクします。

このあたりは、普段から実際にクラウド上をいじっているのかが問われるという話ではあるのかもしれないけれど、正直ちょっとつらい。

サービス名となると統一するのも難しいとは思うけれど、なんとかしてほしいところですね

頑張るを楽しむ

最近聞き始めたPodcastに「ひまじんプログラマーの週末エンジニアリングレッスン」があり、少し前のエピソードで「頑張る人は楽しむ人に勝てない?頑張るを楽しむに変換する技術」と言うものがありました

#347 頑張る人は楽しむ人に勝てない?頑張るを楽しむに変換する技術
https://podcasts.apple.com/jp/podcast/347-%E9%A0%91%E5%BC%B5%E3%82%8B%E4%BA%BA%E3%81%AF%E6%A5%BD%E3%81%97%E3%82%80%E4%BA%BA%E3%81%AB%E5%8B%9D%E3%81%A6%E3%81%AA%E3%81%84-%E9%A0%91%E5%BC%B5%E3%82%8B%E3%82%92%E6%A5%BD%E3%81%97%E3%82%80%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B%E6%8A%80%E8%A1%93/id1601084785?i=1000703794373

元ネタとしては、KDDIアジャイル開発センターに勤める方のスライドのよう

スライドが使われた相手としては、エピソードでは新卒の内定者向けに公演された内容とのことでした。

言っている内容はわかるし、共感はするんだけど内定者に対してこの内容ってどこまで刺さるんだろうな?というのは少し気になった。
KDDIアジャイル開発センターさんが名前的にも人気のありそうで大手だろうしいい人が集まるんだろうな、って思うけれど、このあたり、特にマインドセットの話が実感を伴ってわかるのは個人的には社会人に出てからなんじゃないかな?って思う。

もちろん、「じゃーお前は内定者向けに何話すんだよ?どうせ会社紹介で終わるんだろ」と言われるとぐぬぬとしか言えないような気もする。

T字型人材のところで出てくるスキルセットの内容というのもなかなか見て面白いな、と思った。
ここに出てくるスキルセットに何が並ぶのか?は結構会社によって違いそうで、それって同列に並べて考えるものだっけ?みたいなことを考え出すと、それ自体に意味がないのに無駄に時間を使って考えてしまいそう。

こういった内容を会社名を出してSpeakerdeckとかに公開できるというのは、そういう文化を醸成した人たちの功績だと思うし、同じように何かしら貢献できるような、会社内部事情を排除した形の抽象性を持ち、かつ意味があるような発信ができると面白いのかもしれないと、少しモヤモヤしながら話を聞きました。

あ、Podcast面白かったです。

Whisper.cppがビルドできない

音声の文字起こしは色々あるとは思いますが、ローカルで実行しようと考えた場合に選択肢として上がるのはWhisper.cppではないでしょうか

https://github.com/ggml-org/whisper.cpp

環境としては、様々な環境で動作可能な形なので手元のWindowsで実行しようとしているのですがうまくいきません・・・。

Quick start にある下記コマンドがエラーになってしまうんですよね。

cmake -B build
CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value.  Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.


-- The C compiler identification is MSVC 19.43.34810.0
-- The CXX compiler identification is MSVC 19.43.34810.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.43.34808/bin/Hostx64/x64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.43.34808/bin/Hostx64/x64/cl.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-4.0/Modules/CMakeTestCCompiler.cmake:67 (message):
  The C compiler

    "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.43.34808/bin/Hostx64/x64/cl.exe"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: 'C:/Dev/whisper.cpp/build/CMakeFiles/CMakeScratch/TryCompile-eelwlp'

    Run Build Command(s): "C:/Program Files/CMake/bin/cmake.exe" -E env VERBOSE=1 nmake -f Makefile /nologo cmTC_a73a9\fast
        "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.43.34808\bin\Hostx64\x64\nmake.exe"  -f CMakeFiles\cmTC_a73a9.dir\build.make /nologo -L                  CMakeFiles\cmTC_a73a9.dir\build
    Building C object CMakeFiles/cmTC_a73a9.dir/testCCompiler.c.obj
        "C:\Program Files\CMake\bin\cmake.exe" -E cmake_cl_compile_depends --dep-file=CMakeFiles\cmTC_a73a9.dir\testCCompiler.c.obj.d --working-dir=C:\Dev\whisper.cpp\build\CMakeFiles\CMakeScratch\TryCompile-eelwlp --filter-prefix="メモ: インクルード ファイル:  " -- C:\PROGRA~2\MICROS~3\2022\BUILDT~1\VC\Tools\MSVC\1443~1.348\bin\Hostx64\x64\cl.exe @C:\Users\krote\AppData\Local\Temp\nmDA0F.tmp
    testCCompiler.c
    Linking C executable cmTC_a73a9.exe
        "C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --msvc-ver=1943 --intdir=CMakeFiles\cmTC_a73a9.dir --rc=rc --mt=CMAKE_MT-NOTFOUND --manifests -- C:\PROGRA~2\MICROS~3\2022\BUILDT~1\VC\Tools\MSVC\1443~1.348\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\cmTC_a73a9.dir\objects1.rsp @C:\Users\krote\AppData\Local\Temp\nmDA8D.tmp
    Visual Studio Incremental Link with embedded manifests
    Create CMakeFiles\cmTC_a73a9.dir/manifest.rc
    Create empty: CMakeFiles\cmTC_a73a9.dir/embed.manifest
    RC Pass 1:
    rc /fo CMakeFiles\cmTC_a73a9.dir/manifest.res CMakeFiles\cmTC_a73a9.dir/manifest.rc
    RC Pass 1: command "rc /fo CMakeFiles\cmTC_a73a9.dir/manifest.res CMakeFiles\cmTC_a73a9.dir/manifest.rc" failed (exit code 0) with the following output:
    no such file or directoryNMAKE : fatal error U1077: '"C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --msvc-ver=1943 --intdir=CMakeFiles\cmTC_a73a9.dir --rc=rc --mt=CMAKE_MT-NOTFOUND --manifests -- C:\PROGRA~2\MICROS~3\2022\BUILDT~1\VC\Tools\MSVC\1443~1.348\bin\Hostx64\x64\link.exe /nologo @CMakeFiles\cmTC_a73a9.dir\objects1.rsp @C:\Users\krote\AppData\Local\Temp\nmDA8D.tmp' : リターン コード '0xffffffff'
    Stop.
    NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.43.34808\bin\Hostx64\x64\nmake.exe"  -f CMakeFiles\cmTC_a73a9.dir\build.make /nologo -L                  CMakeFiles\cmTC_a73a9.dir\build' : リターン コード '0x2'
    Stop.

エラーメッセージからは”C:\Program Files\CMake\bin\cmake.exe”が存在しないようにも見えますが、ファイルとしてはいるんですよね。

うーん、なんだかんだ言って、プログラミングよりもこういう環境構築のほうが時間かかるし、精神力をごっそり持っていかれますね。。

Claude codeを少し使ってみた感想

先日セットアップしたClaude code。
個人開発プロジェクトとして作っている、Electronアプリで色々とプロンプトを試しています。
面白いです

自分でコードして、ビルドしてみたら失敗して、調整して、、、って繰り返すのを見ていると、いや、本当人間っぽいなと思ってしまいます。

ただ、コーディングスピードは流石に早く、それなりのボリュームを持った作業をさせると、一度に大量のコードが書かれるために、正直これを読んでいたらこういうツールを使っている意味が薄くなりそうだなと思いました。

動かしてみてうまくいかなければ、それはコードを確認するのではなくプロンプトで指示を投げるような形でしょうか。
そういう意味で、変なデグレードをなくすためにテストコードを書かせながら進めることが大事になりそうです。

一方で、何かしらトラブルが有るたびにプロンプトで指示を与えるということが本当に正しいやり方なんだっけ?と思うと必ずしもそうではなく、コードを読まないといけないシーンはそれなりにあるはず。
そう考えると、コーディングなどに対する理解は必要で。。。いや、それすらプロンプトでAIによるコードの解説を受けながら問題を特定するようになるのだろうか・・・?
うーん、そのほうが現実的なのかもしれない。

誰がどの程度使うことになるのか?

そう考えると、若手に使わせたほうがチームの生産性は上がるかもしれないが一方で学ぶ機会を失うことにもなりかねない懸念はあります。

また、全員が使うのか・・・?協力会社さんがいる場合は・・・?

使ったほうが生産性やスピードが上る可能性は高い一方で、使いこなせないとひたすらプロンプトを打ち続けることになり課金額がそれなりに行くことが考えられます。

もちろん、人件費のほうが高いケースが多いとは思いますが、必要最低限なプロンプトで最大の結果を得るような評価基準が将来のエンジニア評価で用いられる可能性もありそうです。

手でコードを書くという行為と、AIにコード生成させるという行為。
ケースによって違うとは思いますが、このあたりのバランスは試行錯誤を通じて作り上げていく必要があるのかもしれません。

useEffect, useCallback, useMemoに関しての使い分け

Claudeに課金をしたので、先日より取り組んでいるElectron製のアプリをちまちまと助けを借りながらいじっているのですが、

まずは、提示された内容を元に書き写すような形で進めています。

その中で、AIあるあると言えばあるある何でしょうけれど、生成されるコードがコロコロ変わる問題にぶち当たっています。

結局のところ、目的を達成する上でプログラミングの書き方としては複数のやり方があって、その背景をAIに伝えない限りはどの手法が適切なのかはわからず、その生成されるコードが変わるわけですね。

言葉で言ってしまえば、そりゃそうなんだけど、なかなかのストレスです。
完全に任せるわけではない、AIサポートの開発における難しさを感じますね。。。

こういうものを見ていると、結局コードに関しての知識は必要になりそうだな、という気がしてきます。

というわけで、今回は自分の学習記録として、useEffectとuseCallback。そして調べているうちに出てきたuseMemoに関して書いてみようと思います。

useEffect – 副作用の管理

特徴

  • コンポーネントのレンダリング後に実行される
  • DOM操作、データフェッチング、購読、タイマーなどの副作用を扱う
  • クリーンアップ関数を返すことで、コンポーネントのアンマウント時や依存配列の値が変わる前に実行される処理を定義できる

使用例

import React, { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // 副作用: APIからデータをフェッチ
    setLoading(true);

    // userIdが変わるたびに新しいユーザーデータを取得
    fetch(`https://api.example.com/users/${userId}`)
      .then(response => response.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      });

    // クリーンアップ関数
    return () => {
      // コンポーネントのアンマウント時やuserIdが変わる前に実行
      console.log('User profile cleanup');
    };
  }, [userId]); // 依存配列: userIdが変わったときだけ実行

  if (loading) return <div>Loading...</div>;
  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
}

いつ使うべきか

  • 外部データの取得
  • イベントリスナーの設定と解除
  • DOM要素の直接操作
  • タイマーの設定とクリア
  • 外部サービスへの購読と解除

useCallback – 関数のメモ化

特徴

  • 関数をメモ化し、不要な再生成を防ぐ
  • 依存配列の値が変わるまで、同じ関数インスタンスを保持する
  • 子コンポーネントに渡す関数のパフォーマンス最適化に役立つ

使用例

import React, { useState, useCallback } from 'react';

// 子コンポーネント(React.memoでメモ化)
const ExpensiveList = React.memo(({ items, onItemClick }) => {
  console.log('ExpensiveList rendered');
  return (
    <ul>
      {items.map(item => (
        <li key={item.id} onClick={() => onItemClick(item.id)}>
          {item.name}
        </li>
      ))}
    </ul>
  );
});

function ItemManager() {
  const [items, setItems] = useState([
    { id: 1, name: '項目1' },
    { id: 2, name: '項目2' },
  ]);

  const [count, setCount] = useState(0);

  // useCallbackを使用して関数をメモ化
  const handleItemClick = useCallback((id) => {
    console.log(`Item ${id} clicked`);
  }, []); // 空の依存配列: 関数は再作成されない

  return (
    <div>
      <h1>アイテム管理</h1>
      <ExpensiveList items={items} onItemClick={handleItemClick} />
      <div>
        <p>カウント: {count}</p>
        <button onClick={() => setCount(count + 1)}>
          カウント増加
        </button>
      </div>
    </div>
  );
}

いつ使うべきか

  • `React.memo`でラップされた子コンポーネントに関数を渡す場合
  • `useEffect`の依存配列に関数を含める場合
  • イベントハンドラーが複雑で、不要な再作成を避けたい場合
  • 関数が他のフックの依存関係になっている場合

useMemo – 値のメモ化

特徴

  • 計算結果をメモ化し、不要な再計算を防ぐ
  • 依存配列の値が変わるまで、前回の計算結果を再利用する
  • 計算コストが高い処理の最適化に特に役立つ

使用例

import React, { useState, useMemo } from 'react';

function ExpensiveCalculation({ numbers }) {
  const [count, setCount] = useState(0);

  // 計算コストが高い処理をuseMemoでメモ化
  const sumResult = useMemo(() => {
    console.log('Heavy calculation running...');
    // 重い計算の例
    return numbers.reduce((total, num) => {
      // 人為的に処理を重くする
      for (let i = 0; i < 1000000; i++) {}
      return total + num;
    }, 0);
  }, [numbers]); // 依存配列: numbersが変わった時だけ再計算

  return (
    <div>
      <h2>計算結果: {sumResult}</h2>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        カウント増加(計算には影響しない)
      </button>
    </div>
  );
}

function App() {
  const [numbers, setNumbers] = useState([1, 2, 3, 4, 5]);
  return (
    <div>
      <ExpensiveCalculation numbers={numbers} />
      <button onClick={() => setNumbers([...numbers, numbers.length + 1])}>
        数字を追加
      </button>
    </div>
  );
}

いつ使うべきか

  • 計算コストが高い処理の結果をキャッシュしたい場合
  • レンダリングごとに再生成したくないオブジェクトがある場合
  • 大きな配列やオブジェクトの変換や加工を行う場合
  • コンポーネントの再レンダリングが頻繁に発生する場合

まとめ

結局のところ、どこまでキャッシュさせることが可能な内容何だっけ?ってところなんでしょうね。

計算コストが高くても、再レンダリングが頻繁に発生しようとも、表示内容が再計算必要なものであればuseEffectにするしかないんだろうし。。。くらいに覚えておくことにします!