I recently was looking for a way to only react to a change after the first time my component was rendered.
As example:
function NameInput() {
const [name, setName] = createSignal("");
const [nameError, setNameError] = createSignal<string | null>(null);
createEffect(() => {
setNameError(name().length > 0 ? null : "Name is required");
})
return <div>
<input type="text" placeholder="Name" value={name()} onInput={(e) => setName(e.currentTarget.value)} />
<Show when={nameError()}>
<div>{nameError()}</div>
</Show>
</div>
}
However, this would immediately set the error.
The question now is how to only run the createEffect after the initial render on change.
I could not find this anywhere. I will post my solution as an answer here for anyone who stumbles across the same scenario.
So the tricked that worked for me was the on
function combined with defer: true
:
function NameInput() {
const [name, setName] = createSignal("");
const [nameError, setNameError] = createSignal<string | null>(null);
createEffect(on(name, (name) => {
setNameError(name.length > 0 ? null : "Name is required");
}, { defer: true }));
return <div>
<input type="text" placeholder="Name" value={name()} onInput={(e) => setName(e.currentTarget.value)} />
<Show when={nameError()}>
<div>{nameError()}</div>
</Show>
</div>
}