Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What's the reason for limiting setting the initial value only once? #52

Closed
schiller-manuel opened this issue Oct 21, 2023 · 10 comments · Fixed by #53
Closed

What's the reason for limiting setting the initial value only once? #52

schiller-manuel opened this issue Oct 21, 2023 · 10 comments · Fixed by #53
Labels

Comments

@schiller-manuel
Copy link
Contributor

The docs say about useFieldInitialValue:

Initial values can only be set once per scope. Therefore, if the initial value used is changed during rerenders, it won't update the atom value.

But where does this limitation come from?
Why can't the initial value be updated as follows?

function useFieldInitialValue<Value>(
  fieldAtom: FieldAtom<Value>,
  initialValue?: Value,
  options?: UseAtomOptions,
): UseFieldInitialValue {
  const field = useAtomValue(fieldAtom, options);
  const store = useStore(options);

  useEffect(() => {
    if (initialValue === undefined) {
      return;
    }
    if (store.get(field._initialValue) === initialValue) {
      return;
    }
    if (!store.get(field.dirty)) {
      store.set(field.value, initialValue);
    }
    store.set(field._initialValue, initialValue);
  }, [store, field._initialValue, field.value, field.dirty, initialValue]);
}
@jaredLunde
Copy link
Collaborator

what's the use case?

@jaredLunde
Copy link
Collaborator

i think the biggest annoyance would be forcing people to use useMemo on their initial values (objects, arrays, etc) but i don't recall what other reason i had if there was one

@schiller-manuel
Copy link
Contributor Author

I have an edit form where the data is loaded through react-query which uses an stale-while-revalidate caching strategy. This means the form is populated with possibly outdated data, then the data is reloaded in the background while the form is already mounted and then some fields' initial value may be updated.

@schiller-manuel
Copy link
Contributor Author

BTW: could the "first" initial values be set using (useHydrateAtoms)[https://github.com/pmndrs/jotai/blob/main/src/react/utils/useHydrateAtoms.ts] and only subsequent changes to the initial value would be done through useEffect?

@jaredLunde
Copy link
Collaborator

Hmm that's a reasonable case. I think I might have used useHydrateAtoms in an older version but the API didn't work with things like the the store.get(field.dirty) check. You cool to submit a PR?

@schiller-manuel
Copy link
Contributor Author

do you think that equality check I added in the above code is necessary?

@jaredLunde
Copy link
Collaborator

Should the expected behavior for going from defined to undefined be that the value clears? It seems so, right? In that case the check would have to go

@schiller-manuel
Copy link
Contributor Author

schiller-manuel commented Oct 23, 2023

I played around with removing initialValue === undefined, turns out would cause issues if one uses useFieldInitialValue in combination with e.g. useInputField as the latter would issue a call to useFieldInitialValue with initialValue=undefined.

So we would need another value as a "reset" signal, how about RESET?

export function useFieldInitialValue<Value>(
  fieldAtom: FieldAtom<Value>,
  initialValue?: Value | typeof RESET,
  options?: UseAtomOptions
): UseFieldInitialValue {
  const field = useAtomValue(fieldAtom, options);
  const store = useStore(options);

  React.useEffect(() => {
    if (initialValue === undefined) {
      return;
    }
    if (!store.get(field.dirty)) {
      store.set(field.value, initialValue);
    }
    store.set(field._initialValue, initialValue);
  }, [store, field._initialValue, field.value, field.dirty, initialValue]);
}

schiller-manuel added a commit to schiller-manuel/form-atoms that referenced this issue Oct 23, 2023
schiller-manuel added a commit to schiller-manuel/form-atoms that referenced this issue Oct 23, 2023
github-actions bot pushed a commit that referenced this issue Oct 23, 2023
# [3.2.0](v3.1.0...v3.2.0) (2023-10-23)

### Features

* initial value can be updated ([#52](#52)) ([#53](#53)) ([d8d463c](d8d463c))
@github-actions
Copy link

🎉 This issue has been resolved in version 3.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@MiroslavPetrik
Copy link
Member

@schiller-manuel I'm revisiting the hydration as the current hook fails to initialize the form when rendered on the server (Next.js)

BTW: could the "first" initial values be set using (useHydrateAtoms)[https://github.com/pmndrs/jotai/blob/main/src/react/utils/useHydrateAtoms.ts] and only subsequent changes to the initial value would be done through useEffect?

https://github.com/form-atoms/field/blob/main/src/hooks/use-hydrate-field/useHydrateField.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants