redux-form: Cannot use a higher-order function in Field Validation
Are you submitting a bug report or a feature request?
Bug
What is the current behavior?
When using field level validators, I am unable to use a higher order function to produce the validation function
This works:
const required = value => (value ? undefined : 'Required')
<Field
label="Email"
name="email"
component={InputField}
validate={required}
placeholder="email"
type="text"
/>
This DOES NOT work:
const required = (msg = 'Default Message') => value => (value ? undefined : msg)
<Field
label="Email"
name="email"
component={InputField}
validate={required('Message Override')}
placeholder="email"
type="text"
/>
What is the expected behavior?
I would expect to pass into the field validator a returned function that matches the validator interface even if it was produced by a higher order function
Sandbox Link
https://codesandbox.io/s/G6ARklAMr
What’s your environment?
Redux Form: 7.0.3 OS: macOS Browser: Chrome 60
Other information
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 9
- Comments: 24 (4 by maintainers)
I’m more than just “an issues helper”. 😄 Two things:
Okay, this is silly. The form doesn’t need to be reregistered, the form component just needs to be notified of a new validation function.
That said, and perhaps I should write a medium post about this…
Creating a new function for a prop in
render()
is an anti-pattern.It [almost always] requires that the child rerender itself, when
require('This field is required')
always generates the exact same function. Memoizing can get you some benefits here, for sure, as would @danielrob’s other example of saving them asthis.validateUsername
-type members.It would be wonderful if you could do
validate={require('Error message')}
, because it looks so beautiful, but that’s not the way React works at the moment.Hope that helps.
@gabrielhpugliese ok the latest: You must define your validation functions outside of your render method. Additionally if they are a higher order function which receive props you should instantiate them when the component mounts / on instantiation.
So either (option 1):
Or something like (option 2):
Or (option 3)
Please note I’m just doing this off the top of my head, and I’m primarily an issues helper and haven’t tried this on my personal project yet, so this is just my understanding presently.
Is this a good blog post to change your minds about this? https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
Any plans on fixing this or reverting to 6.8? Maybe I’m missing something, but is there any reason to enforce specific usage pattern on users instead of letting them decide and tackle their own performance problems (if they even exist at all, @gabrielhpugliese got a point here)?
@gabrielhpugliese right so tl;dr the new API as it stands means that you must optimise, you can’t generate a new function every render - you must either bind during lifecycle methods/instantiation or use memoization if you have a validator HOF.