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

Accessing form error array using form.useStore and destructuring can cause react update depth issue #902

Open
craigbehnke opened this issue Aug 12, 2024 · 8 comments

Comments

@craigbehnke
Copy link

Describe the bug

When using destructuring, the form.useStore hook returns an error array that appears to change on every render. This then causes a react update depth issue.

Your minimal, reproducible example

https://stackblitz.com/edit/tanstack-form-oryfsj?file=README.md

Steps to reproduce

  1. Access the errors array using destructuring, like so:
 const {errors}: {errors: ValidationError[]} = form.useStore(state => ({
    errors: state.errors
  }))
  1. Use the errors array as a dependency to a react hook, such as useEffect or useMemo
  2. Observe that this react hook is perpetually called.

Please see the provided repro.

Expected behavior

As a user, I want the error array to be updated only when the error array changes.

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

  • OS: MacOS
  • Browser: Chrome/Safari
  • Typescript/React

TanStack Form adapter

react-form

TanStack Form version

v0.29.1

TypeScript version

5.5.4

Additional context

No response

@jackcoup
Copy link

jackcoup commented Oct 26, 2024

I also get this almost every time I use form.useStore((state) => state.values) really not ideal.

@SiddOnKeys
Copy link

did u find a fix or any way around it, its causing issues for me and I'm on a deadline lol

@jackcoup
Copy link

jackcoup commented Nov 3, 2024

I believe I used form.useField() for each prop

@Balastrong
Copy link
Member

I'm sorry but const errors = form.useStore((state) => state.errors) seems to be working fine, I think I don't understand where's the problem.

What feature are you trying to implement?

@craigbehnke
Copy link
Author

@Balastrong It's been a bit, but what I was trying to achieve was to have 1 hook that would return the errors and other properties, i.e.

// My one hook to rule them all
const {isValid, isPristine, isSubmitted, isSubmitting,errors} = form.useStore(
        state => ({
            canSubmit: state.canSubmit,
            isPristine: state.isPristine,
            isSubmitted: state.isSubmitted,
            isSubmitting: state.isSubmitting,
            errors: state.errors
        })
    )

Because of this bug (and after a extended debugging session) I had to split it into 2 different hook calls so that it would work:

// The main hook
const {isValid, isPristine, isSubmitted, isSubmitting} = form.useStore(
        state => ({
            canSubmit: state.canSubmit,
            isPristine: state.isPristine,
            isSubmitted: state.isSubmitted,
            isSubmitting: state.isSubmitting
        })
    )
// The separate error hook to bypass the bug
const errors = form.useStore(state => state.errors)

@Balastrong
Copy link
Member

Ok! I don't have a ready answer sadly, but I understood the issue, thanks :D

@crutchcorn
Copy link
Member

This is a complex issue that is understandably a major headache for our users.

While researching a fix, we've also found an issue with how we handle derived state: #1036

Needless to say, we're working on a broader scope fix to this problem rather than a band-aid. This starts with:

TanStack/store#40
And #1038 (via dogfooding TanStack/store#40 )

This might be a larger body of work than anticipated, so please standby while we work hard on making this a reality

@crutchcorn
Copy link
Member

Image

Happy to report that we've achieved a fix in the #1038 branch 🎉

We'll work on having this fix out soon

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

No branches or pull requests

5 participants