Giter Site home page Giter Site logo

Comments (16)

rlaffers avatar rlaffers commented on July 18, 2024 2

For the use case: please see my first comment. The resolver may need access to additional data (aside from what is passed to it as arguments). The documentation does not seem to mention this limitation (only one validationResolver per component), therefore I reported it. IMO, it is needlessly limiting and breaks user expectations silently. Thanks for your efforts though, great lib.

from documentation.

kotarella1110 avatar kotarella1110 commented on July 18, 2024 2

related #192

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024 1

The resolver may need access to additional data (aside from what is passed to it as arguments).

The reason why I introduced validationContext, the lib itself cache validationResolver. Will validationContext solve your problem? if so I will update the doc to reflect the caching mechanism on the website.

from documentation.

rlaffers avatar rlaffers commented on July 18, 2024 1

To solve my use case, I did roughly this:

export default function App() {
  // create the context object in first render of this coemponent
  // useMemo does not come with semantic guarantee, use lodash.memoize or similar
  // see https://reactjs.org/docs/hooks-reference.html#usememo
  const context = useMemo(() => ({}), [])

  const date = new Date();
  console.log("date in render", date);
  // mutate the context object
  context.date = date;

  const { register, handleSubmit, errors } = useForm({
    mode: "onBlur",
    validationResolver,
    validationContext: context
  });

I..e. mutation of the memoized context object created during the first render of the component. While this may not be the best practice (mutated objects!), it works for me (until perhaps change is made to the hook to prevent memoizing the passed validationContext).

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024 1

I will update the doc on this part:

validationResolver: will be cached inside react-hook-form, because you want to cache the validation rules instead change during render, same as validation schema.

validationContext: is not cached and you can change then as your component gets re-rendered.

let me know if above makes sense.

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024 1

hey @rlaffers i have fixed the cache issue with validationContext, will be released in the next patch.

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024

This should patch this issue: https://codesandbox.io/s/react-hook-form-validationresolver-cq2rh it's due to validationContext is not memorized.

from documentation.

rlaffers avatar rlaffers commented on July 18, 2024

Thanks for your reply. Indeed, when the validationResolver is memoized (its identity does not change in between renders), the issue does not exist. However, your suggested change does not fix the actual problem.
Having the validationResolver change its identity in between renders is a valid use case I think. Let me provide some background. In my case, I need to access some additional data in my validation resolver. Standard way of doing this in JS is creating a closure over those data.

const createResolver = options => data => {
  // do validation of data using those options
}
export default function App() {
  const options = {} // this is a dynamic object. Think some external state. Cannot be memoized and can change on each render.
  const resolver = createResolver(options)
  const { register, handleSubmit, errors } = useForm({
    mode: "onBlur",
    validationResolver: resolver,
  });
  // trimmed the rest
}

In short, when a new validationResolver function is created and passed to useForm during subsequent renders, it breaks validation.

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024

can you use validationContext? take a look my codesandbox above.

from documentation.

rlaffers avatar rlaffers commented on July 18, 2024

Yes, I looked at it but it bypasses the actual issue which I reported. In your codesandbox, there is only a single validationResolver function:

const validationResolver = resolver;

When I changed it so that there is a different validationResolver on each render, it fails:

const validationResolver = resolver.bind(null)

https://codesandbox.io/s/react-hook-form-validationresolver-tiyde

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024

what's the use case for different validationResolver for a single form?

FYI: we are not supporting that type of usage at the moment.

from documentation.

rlaffers avatar rlaffers commented on July 18, 2024

I see your point. Passing those data with validationContext would solve my problem if validationContext was not memoized inside the hook.
Please see:
https://codesandbox.io/s/react-hook-form-validationresolver-640tr

The hook memoizes the context object from the first render. What I would need during validation is access to the context object passed to useForm function during the most recent render.

from documentation.

rlaffers avatar rlaffers commented on July 18, 2024

@bluebill1049 Yes, that makes sense. Just note that currently validationContext is being cached in useForm from the first render (see https://codesandbox.io/s/react-hook-form-validationresolver-640tr). As of now, the only way to work around this is to create a memoized validationContext object on the app level and pass that to the useForm hook. Passing a fresh validationContext object on each render will not work.
I think it is due to handleChangeRef.current which is a closure over the first validationContext object passed to the hook (see https://github.com/react-hook-form/react-hook-form/blob/master/src/useForm.ts#L515)

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024

in fact can you try it in this codesandbox? https://codesandbox.io/s/react-hook-form-validationresolver-cq2rh

from documentation.

richardanewman avatar richardanewman commented on July 18, 2024

I will update the doc on this part:

validationResolver: will be cached inside react-hook-form, because you want to cache the validation rules instead change during render, same as validation schema.

validationContext: is not cached and you can change then as your component gets re-rendered.

let me know if above makes sense.

what about just creating a setValidationSchema and letting developers call setValidationSchema whenver they need to apply a different schema to the entire form? I'm currently trying to implement the resolver but not having any luck.

from documentation.

bluebill1049 avatar bluebill1049 commented on July 18, 2024

I will update the doc on this part:
validationResolver: will be cached inside react-hook-form, because you want to cache the validation rules instead change during render, same as validation schema.
validationContext: is not cached and you can change then as your component gets re-rendered.
let me know if above makes sense.

what about just creating a setValidationSchema and letting developers call setValidationSchema whenver they need to apply a different schema to the entire form? I'm currently trying to implement the resolver but not having any luck.

what's your issue? next major version resolver will be the standard way to validate external schema and conditions.

from documentation.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.