Releases: wsmd/react-use-form-state
0.9.0
🚀 Features
Custom input validation errors
It's now possible to specify custom validation errors for invalid inputs. These errors can be retrieved from the form state for rendering purposes.
A validation error can be specified using the existing validate
method. An input is considered invalid if this method returns false, non-empty strings, non-empty objects, non-empty arrays, etc.
<input
{...password({
name: 'password',
validate: (value, values, event) => {
const errors = {};
if (!value) {
errors.required = 'Password is required';
}
if (!STRONG_PASSWORD_REGEX.test(value)) {
errors.weak = 'Password is not strong enough';
}
return errors; // empty objects are not considered errors!
},
})}
/>
When this input is invalid, you'll notice the returned value from the validate method available in the form state under errors.password
.
{
errors: {
// the value of errors.password is determined via the validate method
password: {
weak: 'Password is not strong enough',
required: 'Password is required',
},
}
}
Further reading:
- https://github.com/wsmd/react-use-form-state#custom-input-validation
- https://github.com/wsmd/react-use-form-state#input-options
✨ Improvements
The input's validate
method gives you access to the change/blur event
It's now possible to access the change/blur event via the validate method. This can helpful if you want to access the underlying DOM node to perform certain checks.
<input
required
pattern={VALID_USERNAME_REGEX}
minLength={4}
text({
name: 'username',
validate: (value, values, e) => {
if (e.target.validity.valueMissing) {
return 'Value is required';
} else if (e.target.validity.tooShort) {
return 'Value is too short';
} else if (e.target.patternMismatch) {
return 'Value does not match the required';
}
},
})
/>
Generated props are now memoizable (no more unnecessary re-renders)
In the past a change to an input resulted in re-rendering the entire form. That is not longer the case. The props generated by the input calls are now memoizable. This means that memoized input components will not re-render if their values remain the same.
const MemoizedInput = React.memo((props) => (
<input {...props} />
));
const MyForm = () => {
const [formState, { text, password }] = useFormState();
return (
<>
{/* these inputs only re-render if their values actually changed */}
<MemoizedInput {...text('username')} />
<MemoizedInput {...password('password')} />
</>
)
}
📦 Other Changes
A special thanks to all the contributors that helped make this release possible! 🙇♂️
0.8.0
🚀 Features
Added an optional API to pair <label>
tags with their inputs
A convenience API is now provided to hep with paring a <label>
tag to a input specific component.
function FormWithLabels({ initialState }) {
const [formState, { label, text }] = useFormState(initialState, {
withIds: true
});
return (
<form>
<label {...label('name')}>Full Name</label>
<input {...text('name')} />
</form>
);
}
Further reading:
- https://github.com/wsmd/react-use-form-state#labels
- https://github.com/wsmd/react-use-form-state#formoptionswithids
Added support for input-level custom validation and event handlers
Inputs now accept a custom validation function as well as onBlur
and onChange
event handlers.
<input
{...password({
name: 'password',
onChange: e => console.log(`input was changed to ${e.target.value}`),
validate: value => STRONG_PASSWORD_REGEX.test(value)
})}
/>;
Further reading:
- https://github.com/wsmd/react-use-form-state#advanced-input-options
- https://github.com/wsmd/react-use-form-state#input-options
✨ Improvements
Inputs are now validated onChange
by default
The validity of the input will be calculated as the input's value changes, and will be reflected in state.validity
.
📦 Other Changes
- Dev dependency maintenance (#30)