Date クラスで躓いたこと

この記事を作った動機 Date クラスの仕様で、引っかかった部分があるのでそのことについて記録をする。具体的には、getMonthメンバ関数を使おうとしたとき、思っているのとは違う結果になったというのがある。 内容 Date クラスの getMonth関数は、MDNに書かれているように、ゼロからスタートする値である。1月は、この関数の戻り値として、0 と表現され、12月は 11 として表現される。 The return value of getMonth() is zero-based, which is useful for indexing into arrays of months, for example: 具体的に引っかかったところ createDateStringという関数を作っていて、文字列として"YYYY/MM/DD"のような形式で今いつかということを返すようにしようとしていた時、月の部分が一つ前になっていることに気づいた。 createDateStringを実行した日を2025/10/29として、問題のあるコードと、そうでないコードの違いを以下に示す。 問題のコード 帰ってくる戻り値は、2025/9/29。 export function createDateString(){ // yyyy/mm/dd const currentDate = new Date() let dateString = "" dateString += String(currentDate.getFullYear()) + "/" dateString += String(currentDate.getMonth()) + "/" dateString += String(currentDate.getDate()) return dateString } 修正したコード 帰ってくる戻り値は、2025/10/29。 export function createDateString(){ // yyyy/mm/dd const currentDate = new Date() let dateString = "" dateString += String(currentDate.getFullYear()) + "/" dateString += String(currentDate.getMonth() + 1) + "/" dateString += String(currentDate.getDate()) return dateString } 参考にしたサイトとか Date - JavaScript | MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date (2025年10月29日)

October 29, 2025

Websocket を自動で再接続したい

この記事を作った動機 Websocket を使ったフロントエンドで、自動的に接続が途切れたら再接続するコードを書くときに躓いたので、その記録をする。 Websocket の接続に関するエラーハンドリング Websocket が接続失敗したときに、やらせたい処理がある場合は、try-catch は使えない。接続に関する問題に対処するには、コールバック関数として、“error"イベントが発火されたときに処理を登録する必要がある。 Websocket は、非同期で実行されるため try-catch では接続できなかったときのエラーを拾えないようである。 うまくいかない例 // この例だと、reconnect 関数が実行されることはない。この形だと、WebScoket クラスに渡したパラメータ異常しか拾えない。 const setWebsocket = useDatabaseStore.setState; try{ const websocket = new WebSocket("ws://localhost:50097") setWebsocket({ websocket: websocket }) }catch(e){ console.log(e) reconnect() } うまくいく例 const setWebsocket = useDatabaseStore.setState; const websocket = new WebSocket("ws://localhost:50097") websocket.onerror = () => { reconnect() } setWebsocket({ websocket: websocket }) const setWebsocket = useDatabaseStore.setState; const websocket = new WebSocket("ws://localhost:50097") websocket.addEventListener("error",reconnect) setWebsocket({ websocket: websocket }) 参考にしたサイトとか ChatGPT https://chatgpt.com/ (2025年9月29日) WebSocket: close イベント - Web API | MDN https://developer.mozilla.org/ja/docs/Web/API/WebSocket/close_event (2025年9月29日) WebSocket: error イベント - Web API | MDN https://developer.mozilla.org/ja/docs/Web/API/WebSocket/error_event (2025年9月29日) WebSocket: WebSocket() コンストラクター - Web API | MDN https://developer.mozilla.org/ja/docs/Web/API/WebSocket/WebSocket (2025年9月29日)

September 29, 2025

Hooks の宣言、定義で躓いたこと

この記事を作った動機 React で useState なり useEffect なり hooks と呼ばれている状態変数と関係があるものを使うときは厳し目の条件があるようで、それが原因で動かないということがあった。 そこでどこに気をつければ良さそうか、公式ドキュメントを見たり、調べてみたりして、自分なりの理解でとりあえず記録しようということになった。 環境 Vite React TypeScript Tailwind CSS zustand hooks とは use〇〇 という感じで定義されている React の API 群の事っぽい。現状の体感としては、状態変数に関係する React の API のことを包括的に hooks とよんでいるように見える。以下は hooks の例である。 useState useRef useEffect 状態変数管理ライブラリで使う関数の一部? zustand の例 // 定義 --------------------------------------------- // 定義 --------------------------------------------- import { useEffect, useState } from "react" import { create } from "zustand"; type DatabaseState = { websocket: WebSocket | null; serverIP: string | null; changeServer: (ip: string) => void; closeConnection: () => void; getWebsocket: () => WebSocket | null; }; // hooks 相当の部分の定義 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); // 何かしらのコード } use〇〇 から始まる APIを組み合わせた関数 // 定義 --------------------------------------------- // 定義 --------------------------------------------- // 上記の ”zustand の例” と同じ // 定義 --------------------------------------------- // 定義 --------------------------------------------- // useEffect の React API としての hooks や // useDatabaseStore の zustand (状態変数管理ライブラリの関数) としての hooks // を組み合わせてた 任意の定義の hooks の例 export function useDatabaseEffects() { const serverIP = useDatabaseStore((s) => s.serverIP); const setWebsocket = useDatabaseStore.setState; useEffect(() => { if (!serverIP) return; const ws = new WebSocket(serverIP); setWebsocket({ websocket: ws }); // return () => { // ws.close(); // }; }, [serverIP, setWebsocket]); } 気にしたほうが良さそうなこと コンポーネント内に hooks は書く コンポーネント内のなるべく先頭に hooks は書く コンポーネントの関数内のスコープからハズレたところには hooks は定義、宣言はできない。以下の部分が基本的にポイントな気がする。 if 文の中 loop 内 コールバック関数など、コンポーネント関数のスコープから外れるところ レンダリング部分内部 hooks で定義された状態変数の操作などは、コンポーネント関数内とかに限らず、コールバック内で呼び出したり、書き込んだり比較的自由にできる模様である。 // 何かしらのコード export default function Selector() { const websocket = useDatabaseStore((s) => s.websocket); const [visible,setVisible] = useState(false) const init = useRef(true) const toolbarAddTool = useToggleableStore((s) => s.addToggleable) // zustand (状態変数管理ライブラリ) も関係ある const [index, setIndex] = useState<Info>({ status: "init", errorMessage: "nothing", data: null, }); useEffect(() => { if (!websocket) { setIndex({ status: "error", errorMessage: "No data server connected to.", data: null, }); return; } const handleMessage = (event: MessageEvent) => { const result = JSON.parse(String(event.data)); console.log(result) if (!result.status.includes("error")) { setIndex(result); } else { setIndex({ status: result.status, errorMessage: result.errorMessage, data: null, }); } }; const whenOpened = () => { const request = JSON.stringify({ command: "info", data: null }); websocket.send(request); } websocket.addEventListener("message", handleMessage); websocket.addEventListener("open",whenOpened) // cleanup return () => { websocket.removeEventListener("message", handleMessage); }; }, [websocket]); // 条件分岐やループ、レンダリングや何かしらのコールバック関数内などで、 // hooks を宣言したり、定義することはできないという感じの模様 // しかし、hooks の定義で出てくる set〇〇 などを使ったりして、状態変数を操作したりなどはできる模様 if(init.current){ const toggleable:toggleable = { name: "Selector", setVisibility: setVisible, visibility:visible } toolbarAddTool(toggleable) init.current = false } // 何かしらのコード } エラーの発生と修正例 実際に私がOnenote代替品の作成でコードを書いているときに起こったエラーについて、記録してみる。 ...

September 10, 2025

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

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

この記事を作った動機 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