Closed elzayat closed 4 years ago
I encountered the same issue while working with formik.
React V 16.5.2 Formik V 1.3.2
this is the minimum reproduction of my code.
class DetailsForm extends Component {
render() {
return (
<Formik
initialValues={{
location: '',
}}
onSubmit={(values) => {
this.props.onSubmit(values);
}}
validationSchema={object().shape({
location: string(),
})}
>
{renderProps => {
const {values, touched, errors, handleChange, handleBlur, handleSubmit} = renderProps;
return (
<form className="row" onSubmit={handleSubmit}>
<PlacesAutocomplete value={values.location} onChange={handleChange} />
<div className="form-group col-12">
<button type="submit" className="btn btn-outline-primary">next</button>
</div>
</form>
)
}}
</Formik>
)
}
}
The error I got is this...
Failed prop type: The prop 'children' is marked as required in 'PlacesAutocomplete', but its value is 'undefined'.
Uncaught TypeError: this.props.children is not a function
Any default value I pass won't work here; like null, undefined and empty object. I saw the example from your repo which provides a blank string as a default value. However this is not working with my case.
Can you please help me out here, thank you!
The problem is that <input onChange={handleChange} />
fires handleChange
with an event, while <PlacesAutocomplete onChange={handleChange} />
fires with a value. so Formik can't use it as a callback
works with formik's setFieldValue
: <PlacesAutocomplete onChange={(value) => setFieldValue('city', value)} />
works with formik's
setFieldValue
:<PlacesAutocomplete onChange={(value) => setFieldValue('city', value)} />
Thank you for your reply! But; it is still not working for me
It Works for me
`<Formik initialValues={{ pickup: "" }} onSubmit={(values, actions) => { this.props.getpricelist(values); }} validate={validate} render={({ handleSubmit, setFieldValue, values, errors, touched }) => (
)} />;`
Hey @Kukunin , is there a way we can get it to fire both an event and the value? Because I'm trying to integrate it with formik and I'm facing the same problems as @abhilashrathod . I'm guessing I'll have to clone the repo and modify the way events are handled myself.
EDIT :
function(option, value) {
this.props.handleChange({
target: {
type: 'text', // input type
name: option,
id: option,
value: value,
},
},
{ value },
)
}
The secret to use with Formik is the setFieldValue
function.
Into the onChange
method, of the <PlacesAutocomplete />
component, you'll need to call setFieldValue
to update the formik input value.
This function come from the render({ setFieldValue })
method, provide by the <Formik />
component.
On my case, i'm using the autocomplete inside of a <Field />
component. That has {field, form}
coming from his render
function.
The form
prop contains the setFieldValue
function. Than i pass to the autocomplete.
Something like that:
handleChange({ name, form, search }) {
form.setFieldValue(name, search);
}
renderPlacesAutocomplete({ field, form }) {
return (
<PlacesAutocomplete
value={field.value}
onChange={search => {
this.handleChange({ name: field.name, form, search });
}}
>
{({ getInputProps, getSuggestionItemProps, suggestions }) => {
const additionalProps = {
name: field.name,
className: 'form-input__field',
};
const autocompleteInputProps = getInputProps(additionalProps);
return (
<div className="autocomplete-root">
<input {...autocompleteInputProps} />
<div className="autocomplete-dropdown-container">
{suggestions.map(suggestion => (
<div {...getSuggestionItemProps(suggestion)}>
<span>{suggestion.description}</span>
</div>
))}
</div>
</div>
);
}}
</PlacesAutocomplete>
);
}
render() {
<Field
name={name}
handleBlur={onBlur}
{...inputProps}
render={({ field, form }) => this.renderPlacesAutocomplete({ field, form })}
/>
}
In addition of using setFieldValue()
given from <Formik />
If you are using useField()
or <Field />
as a children of PlacesAutocomplete
and you need the field
/meta
to be available in the parent Component
, you can use a second <Field />
with the same name
prop to pass them down, see example:
With <Field />
<Field name="same-name"> // they got the same name
{({ field, meta }) => (
<div>
<PlacesAutocomplete
value={field.value}
// ...
>
<CustomInput name="same-name" /> // they got the same name
</PlacesAutocomplete>
</div>
)}
</Field>
or
With useField()
const [field, meta] = useField("same-name); // they got the same name
return (
<div>
<PlacesAutocomplete
value={field.value}
// ...
>
<CustomInput name="same-name" /> // they got the same name
</PlacesAutocomplete>
</div>
)
Hope it helps.
it is working with formik