javascriptsolid-js

SolidJS createEffect only on change after initial


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.


Solution

  • 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>
    }