React と addEventListener

この記事を作った動機 React で addEventListener を使ったら、再描画される事に、addEventListener されまくって、例えばマウスボタンが押されたというイベントが発火したときに、無数の同じ処理が走りまくるという事態になった。 これは以下のように、react の要素の一部として書いたときには、起こらなかった。 export function OverlayWindow({ children, arg }:{ children:ReactNode, arg:OverlayWindowArgs }){ // 何かしらのコード if(visible){ return (<div className={OverlayWindowContaierClassName} style={windowPosStyle}> <div className="windowHeader move bg-yellow-600 w-full h-[2rem] justify-center place-items-center align-middle text-center" onMouseDown={windowHandlers.mousedown} // addEventListener 相当 onTouchStart={windowHandlers.touchstart} // addEventListener 相当 > <div className="title h-[1rem] absolute text-white">{arg.title}</div> <div className="close size-[2rem] bg-red-700 ml-auto" onClick={() => {setVisible(false)}}></div> </div> <div className="content bg-gray-900 min-h-[5rem] w-full flex justify-center place-items-center align-middle text-center items-center"> {children} </div> </div>) } } それでとりあえず、解決状態だと思われる、アプリ自体の動作を重くしないレベルの実装にもっていくまでについて、簡易的に記録を取ろうと思い、この記事を作った。 ...

September 10, 2025

記事リスト

この記事を作った動機 単に、このブログの方針として、”自分が参照するノート”としてメインに掲げているところがある。それで、必ずしも “content/posts/idea/research/onenoteAlternativeCreation/” 配下に収まっているわけではなく、色んな所に関係のある記事が散らばっている。 それらをまとめるために、この記事にリンク集みたいな感じで、散らばってしまっている記事をまとめておこうと思った次第である。 記事リスト React コンポーネント内にネストができる関数コンポーネント 変数 Zustand 状態変数管理ライブラリ Hooks の宣言、定義で躓いたこと Websocket を自動で再接続したい TypeScript Date クラスで躓いたこと

September 10, 2025

Zustand 状態変数管理ライブラリ

この記事を作った動機 単に自分用に、zustand の使い方を今 (2025/9/9) わかっている範囲で、書き出してみるだけ。 環境 Vite React TypeScript Tailwind CSS zustand 概要 まだ全然わかっていないが、私の今 (2025/9/9) イメージとしては、「zustand とは、react で言う状態変数の管理に関するライブラリの一つで、親 -> 子 コンポーネントという流れで状態変数を渡していく以外で、コンポーネント間の状態変数を共有、管理することができるもの。」という感じである。 TODO 参照が変わらないと、再描画が起こらないことを書く。例えば、setter 内で、get()したものを直接変更し、set()のところに使うと、参照が同じのため、問題が起こる。 使い方 import import { create } from "zustand"; 宣言例 type DatabaseState = { websocket: WebSocket | null; serverIP: string | null; changeServer: (ip: string) => void; closeConnection: () => void; getWebsocket: () => WebSocket | null; }; export const useDatabaseStore = create<DatabaseState>((set, get) => ({ // 変数の初期化 websocket: null, serverIP: "ws://localhost:50097", // 変数を操作する関数群 changeServer: (ip: string) => { set({ serverIP: ip }); }, closeConnection: () => { const ws = get().websocket; ws?.close(); set({ websocket: null }); }, getWebsocket: () => get().websocket, })); データを呼び出し、利用する export function Acompornent(){ // 他の hooks と同様にコンポーネントのコードの先頭あたりに書く必要がある。 const websocket = useDatabaseStore((s) => s.websocket); console.log(websocket) // 何かしらのコード } 関数を呼び出す export function Acompornent(){ // 他の hooks と同様にコンポーネントのコードの先頭あたりに書く必要がある。 const changeServer = useDatabaseStore((s) => s.changeServer) changeServer("ws://localhost:88091") // 何かしらのコード } 躓いたこと イミュータブルの原則 zustand を使っているときに、どうやっても値を更新しているにも関わらず、再描画が正しくかからないという問題が起こった。これは、同じ参照を持つ変数を変更するという、“ミュータブル"な扱いをしたときに起こるようである。一度宣言された、作られた変数は原則変更しない(できない)というのが、React や zustand といった状態変数の概念の前提にはあるっぽいと私は最終的に考えた。 ...

September 9, 2025

変数

この記事を作った動機 全然まだ私は使い方とか概念をわかってないと思うが、とにかくよく使う hooks について記録を取りたいので、記事を書くだけ。思考の整理とかって感じで書いていて、普通に間違い混ざってると思うし、他の人に参考になるかは怪しい。 react とデータの関係性 React では、データが変更されると UI が連動して更新されたりするという仕組みになっているので、普通の変数ではなく、データのありように合わせて、状態変数と呼ばれるものを使い分ける必要がある。 環境 Vite React TypeScript Tailwind CSS zustand 普通の変数 概要 普通に TypeScript や JavaScript で宣言するような let や var などと書いて宣言する変数たちのことである。これら変数の内容は基本的に React が再描画をかけると内容が初期化されて元の再描画前のデータは消えてしまう。 これを防ぎ、UI 再描画をまたいで変数の値を保持するためには、状態変数を useState なり、 useRef なり宣言して利用する必要があると思われる。 export default function Acompornent(){ // 再描画時には、x:100 y:100 にいちいち初期化されて変更内容が失われる let windowPos = { x: 100, y: 100 } // こちらは再描画時には内容は失われない const [style,setStyle] = useState({ top:0, left:0 }) // このようなコードを書くと windowPos は setStyle されたあと再描画で内容が初期値に戻ってしまう addEventListener("mousemove",(event:MouseEvent) => { // 何かしらのコード windowPos.x = event.screenX windowPos.y = event.screenY // 何かしらのコード setStyle({ top: windowPos.x, left: windowPos.y }) }) return <div style={style} className="fixed">This is styled text.</div> } useState 概要 オーソドックスな状態変数で、データが更新されたとき、UI を再描画させたいという場合に使う。 ...

September 9, 2025

コンポーネント内にネストができる関数コンポーネント

この記事を作った動機 Vite + React + TypeScript の環境でコンポーネント"内部"になにか要素をネストする方法がわかんなかったので記録するだけ。ただ厳密のこのやり方で正しいかはわかっていないが、ChatGPT-5 が出したやり方がとりあえず動いたので記録することにした。今のところ公式ドキュメントとかで今回出すようなやりかたをしているのはまだ見つけられていない。 環境 Vite React TypeScript Tailwind CSS zustand ネストの仕方 ネストできる関数コンポーネントを単体で定義 import {type ReactNode} from "react" export default function Outside1({ children }:{ children:ReactNode }){ return <div className="flex flex-row bg-gray-700 h-[5rem] w-screen top-[5rem] left-0 fixed"> {children} </div> } ネストできる関数コンポーネントをコンポーネント内に定義 import {type ReactNode} from "react" export default function Acompornent(){ // ネストができる関数コンポーネントは必ずしも、このようにコンポーネント内に書いている必要はないと思う。 function Outside({ children }:{ children:ReactNode }){ return <div className="flex flex-row bg-gray-700 h-[5rem] w-screen top-0 left-0 fixed"> {children} </div> } return <div> <Outside> <p>This</p> <p>is</p> <p>children.</p> </Outside> <Outside1> <p>This</p> <p>is</p> <p>children.</p> </Outside1> </div> } 参考にしたサイトとか ChatGPT https://chatgpt.com/ (2025年9月8日) Quick Start – React https://react.dev/learn (2025年9月9日)

September 8, 2025