This might be just an edge-case, not really an issue with the react-form
itself. I still prefer to report this as I am not sure how can I solve it.
It seems like values provided by <Form values={} />
are not available through getValue()
in FormInput
on the "first run".
The input value is set to undefined
when I am trying to setValue( getValue() )
in the onBlur
callback without changing the input default value (it works when i change the value). I believe it should set the input value to its default value provided by <From values={ ... } />
instead of undefined
.
Story:
I've created a custom input in which I verify the given value (in onBlur
) and eventually change it. For example if the input value is 12
it will change to 12:00
, 1:3
becomes01:30
and so on:
Custom input: <HourInput />
import moment from "moment";
import React from "react";
import { FormInput } from "react-form";
export default function ( { field, isForm, ...rest } ) {
return (
<FormInput field={field} isForm={isForm}>
{ ( { setValue, getValue, setTouched } ) => (
<input {...rest}
value={getValue()}
placeholder="00:00"
onChange={ e => setValue( e.target.value ) }
onBlur={ () => { setValue( verifyValue( getValue() ) ) } }
/>
) }
</FormInput>
)
}
function verifyValue( value ) {
const time = moment( value, "HH:mm" );
return time.isValid() ? time.format( "HH:mm" ) : "00:00";
}
I am rendering those inputs in a loop, like so:
class Foo extends Component {
[...]
renderHoursInputs = period => {
const verb = period === "start" ? "Start:" : "End:";
const hours = MenuUtils.parseHours( RestaurantStore.data.hours );
return (
<tr>
<td>{verb}</td>
{ Object.keys( hours ).map( day => (
<td key={`${period}_${day}`}>
<HourInput field={[ "hours", day, period ]} />
</td>
) ) }
</tr>
);
}
render() {
const hours = MenuUtils.parseHours( RestaurantStore.data.hours );
// hours = { day_index : { start : hour, end : hour }, ... ]
// hours = { 1 : { start : "08:00", end : "16:00" }, ... }
return (
<Form onSubmit={...} validate={...} values={ { hours } }>
[...]
{this.renderHoursInputs( "start" )}
{this.renderHoursInputs( "end" )}
[...]
</Form>
}
}
The default value specified in <Form values={...} />
matches the array-like field name and is displayed correctly as you can see:
When I click on the input and change it's value, everything works correctly. The input value is changed and eventually auto-corrected as intended.
The problem appears when I click on the input and then blur it without changing anything. Then it's value is changed to 00:00
(the default one returned by verifyValue
), even if the input had a default value set by the <Form />
:
I've tried to use some kinds of hacks, for example hard-setting the value directly in the input, but then the input becomes controlled (?) and I cannot change it's value anymore:
// rest.value = default value
<input {...rest} value={getValue( rest.value )} />
Any thoughts on how can I solve this issue? I am not sure if I am doing something wrong or if there's a problem with the way react-form
handles defaults values provided by <Form />
.
Using the latest Node.js
and react-form
version.