diff --git a/web/sections/BandSettings.tsx b/web/sections/BandSettings.tsx
index d9a8dc3..fabd04f 100644
--- a/web/sections/BandSettings.tsx
+++ b/web/sections/BandSettings.tsx
@@ -69,7 +69,12 @@ export const BandSettings = ({
setDraft((was) => ({ ...was, name: event.currentTarget.value }))}
+ onChange={(event) => {
+ // Read NOW. React nulls `currentTarget` when the handler returns, and a functional updater
+ // runs after that — so reading it inside one throws on the first keystroke.
+ const value = event.currentTarget.value;
+ setDraft((was) => ({ ...was, name: value }));
+ }}
/>
@@ -78,7 +83,10 @@ export const BandSettings = ({
setDraft((was) => ({ ...was, title: event.currentTarget.value }))}
+ onChange={(event) => {
+ const value = event.currentTarget.value;
+ setDraft((was) => ({ ...was, title: value }));
+ }}
/>
diff --git a/web/sections/BlockSettings.tsx b/web/sections/BlockSettings.tsx
index a919a08..9788aaa 100644
--- a/web/sections/BlockSettings.tsx
+++ b/web/sections/BlockSettings.tsx
@@ -100,7 +100,12 @@ export const BlockSettings = ({
setDraft((was) => ({ ...was, title: event.currentTarget.value }))}
+ onChange={(event) => {
+ // Read NOW — see the note in BandSettings. A functional updater runs after the handler has
+ // returned, and `currentTarget` is null by then.
+ const value = event.currentTarget.value;
+ setDraft((was) => ({ ...was, title: value }));
+ }}
/>
{/*