react material-table formik validation in custom edit component - reactjs

I'm using react-material-table.
I'm trying to validate the row edit.
Everything works fine for "native" material column.
But I had to use a custom editComponent for one column rendering an Autocomplete.
{
title: "test",
field: "foo",
editComponent: (props) => {
return (
<div>
<Autocomplete
onChange={(e, v) => this.handleFooChange(props.rowData.id, v)}
//onChange={(e,v) => props.onChange(v)}
id="people-company"
options={[{ id: 1, name: "bar" }, { id: 2, name: "foo" }]}
getOptionLabel={option => option.name}
value={props.rowData.foo}
filterSelectedOptions
renderInput={params => (
<TextField
{...params}
variant="outlined"
label="company"
placeholder="company"
margin="normal"
fullWidth
/>
)}
/>
</div>
);
},
My MaterialTable define EditRow and EditField
const FormikMTInput = props => {
return (
<Field name={props.columnDef.field}>
{({ field, form, meta }) => {
const { name } = field;
const { errors, setFieldValue } = form;
//console.log("ShowError", errors);
const showError = !!getIn(errors, name);
return (
<div>
<MTableEditField
{...props}
{...field}
error={showError}
onChange={newValue => setFieldValue(name, newValue)}
/>
{errors[field.name] && (
<div style={{ color: "#f44336" }}>{errors[field.name]}</div>
)}
</div>
);
}}
</Field>
);
};
const MuiTableEditRow = ({ onEditingApproved, ...props }) => {
return(
<Formik
validate={values => {
const errors = {};
if (!values.name) {
errors.name = "Required";
}
if (!values.foo) {
errors.foo = "Required";
}
return errors;
}}
initialValues={props.data}
onSubmit={values => {
if (values) {
if (values.name.length > 2 && values.foo)
onEditingApproved(props.mode, values, props.data);
}
}}
render={({ submitForm }) => (
<MTableEditRow {...props} onEditingApproved={submitForm} />
)}
/>
)};
<MaterialTable
title="Editable Preview"
columns={this.state.columns}
data={this.state.data}
components={{
EditRow: MuiTableEditRow,
EditField: FormikMTInput
}}
/>
FormikMTInput is well fired on "default" columns. It is not the case for the overwrited editComponent. How can I pass errors to this column?
Here the sandbox

The problem is, that the current value differs from the rowData value.
So change value={props.rowData.foo} to value={props.value} in the autocomplete, to get the correct value. Previously, the rowData never changed on edit because the row still had the data until you save it.
Additionally, you should pass the already transformed value to the onChange function and not the event like this: onChange={v => props.onChange(v.target.value)}.
if (!id || id === undefined) return; is equal to if (!id) return;because !id returns true for undefined.
Last but not least, you are mutating your state data in
var myData = this.state.data;
myData.forEach(d => {
if (d.id === id) {
d.foo = v;
}
});
which is a no-go. Change it to:
handleFooChange(id, v) {
if (!id) return;
const myData = this.state.data.map(d => d.id === id ? {...d, foo: v} : d);
this.setState({ data: myData });
}

Related

MUI Autocomplete (multiple) controlled values - mysterious input behavior

I am trying to write code to asynchronously search a multiple-select combo upon keyboard entry.
However I found in latest version (5.2.2) a strange behaviour where I cannot explain. I distill the issue below (based on example from MUI's autocomplete page):
import * as React from "react";
import TextField from "#mui/material/TextField";
import Autocomplete from "#mui/material/Autocomplete";
const options = [
{ label: "Option 1", value: 1 },
{ label: "Option 2", value: 2 }
];
export default function ControllableStates() {
// const [value, setValue] = React.useState<any | null>([]);
const value = [];
const [inputValue, setInputValue] = React.useState("");
console.log("Current Value:", value);
return (
<div>
<div>{`value: ${value !== null ? `'${value}'` : "null"}`}</div>
<div>{`inputValue: '${inputValue}'`}</div>
<br />
<Autocomplete
multiple={true}
value={value}
onChange={(event: any, newValue: any | null) => {
//setValue(newValue);
}}
inputValue={inputValue}
onInputChange={(event, newInputValue) => {
setInputValue(newInputValue);
}}
id="controllable-states-demo"
options={options}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Controllable" />}
/>
</div>
);
}
The codeSandbox is as follows: https://codesandbox.io/s/controllablestates-material-demo-forked-ygqp2?file=/demo.tsx
If you try in the codeSandbox, you will be unable to type anything in the TextField field.
However, if you switch the commenting:
const [value, setValue] = React.useState<any | null>([]);
// const value = [];
You will be able to type in the TextField field. What is actually happening here? The value did not change at all.
Can anyone figure out why my first code (where the value is a const empty array) didn't work?
The reason I am asking is that I need to pass in the (controlled) value as props, and then set it to default to [] if it is null. I find that I am unable to type in the TextField due to this defaulting.
First, you could use the Autocomplete component without inputValue and OnInputValue props.
...
<Autocomplete
multiple
value={value}
onChange={(event: any, newValue: any | null) => {
//setValue(newValue);
}}
id="controllable-states-demo"
options={options}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Controllable" />}
/>
But it won't work for the selection, only search will work.
Second, if you want its search as well as selection to work, then you should use more a couple of Autocomplete props.
...
export default function ControllableStates() {
const [value, setValue] = React.useState<any | null>([]);
// you need to set the selected value your own
// const value = [];
const [inputValue, setInputValue] = React.useState("");
console.log("Current Value:", value);
return (
<div>
<div>{`value: ${value !== null ? `'${value}'` : "null"}`}</div>
<div>{`inputValue: '${inputValue}'`}</div>
<br />
<Autocomplete
multiple
value={value}
onChange={(event: any, newValue: any | null) => {
setValue(newValue.map(option => option.value || option));
}}
isOptionEqualToValue={(option, value) => option.value === value}
getOptionLabel={(option) => {
if (typeof option === 'number') {
return options.find(item => item.value === option)?.label;
} else {
return option.label;
}
}}
id="controllable-states-demo"
options={options}
sx={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Controllable" />}
/>
</div>
);
}
As you can see it doesn't need to use the inputValue and onInputChange props as well.
Please make sure if you match the correct types of the selected value and option.
If you are using react-hook-form you can set up the autocomplete by using
multiple to add multiple values,
options: you add the options to be selected
getOptionLabel: to show up the label of the options
onChange: use onChange function of react-hook-form to set the selected values
renderInput: to render the input
import { useForm, Controller } from 'react-hook-form'
import {
Box,
TextField,
Autocomplete,
} from '#mui/material'
const {
...
control,
formState: { errors },
} = useForm()
<Box mt={2}>
<Controller
control={control}
name="industries"
rules={{
required: 'Veuillez choisir une réponse',
}}
render={({ field: { onChange } }) => (
<Autocomplete
defaultValue={
useCasesData?.industries
? JSON.parse(useCasesData?.industries)
: []
}
multiple
disableCloseOnSelect
options={companyIndustryTypes}
getOptionLabel={(option) => option.name}
onChange={(event, values) => {
onChange(values)
}}
renderInput={(params) => (
<TextField
{...params}
label="Type d'industries"
placeholder="Type d'industries"
helperText={errors.industries?.message}
error={!!errors.industries}
/>
)}
/>
)}
/>
</Box>
Note that options in my case companyIndustryTypes is an array of object :
[
{
id: 1,
name: "Accounting",
},
{
id: 2,
name: "Administration & Office Support",
},
...
]

Submitting a form React - MUI v5, delivers a wrong value from one field

I have a react from made with MUI (I'm using MUI v5))
Everything works ok, until I hit submit.
The submitted values are ok except for the select, which is delayed, I mean, suppose I select the first value, and the default value is 0, then hitting submit will say that the selected value is 0, then, if I hit submit once more, immediately, then it says the correct answer, see, it’s kind of delayed by one render of the component.
I wanted to have all values in one object state, but I had to separate some of them, like a date value (uploadDate) and the select value (category value)
This is the simplified code:
const AddVideoAndCategories = ({
addVideo,
getAllCategoriesWithoutVideos,
categories,
categoriesLoaded,
resetDrawerMenuItems,
addDrawerItem,
setCurrentDrawerMenuItems
}) => {
const [ formValues, setFormValues ] = useState(defaultValues);
const [ uploadDate, setUploadDate ] = React.useState(today());
const [ selectedCategory, setSelectedCategory ] = useState('');
const { handleSubmit, reset, control } = useForm();
const navigate = useNavigate();
useEffect(() => {
if (!categoriesLoaded) {
/// Load the categories from the back end to redux
}
}, []);
const handleCategoryChange = (e) => {
setSelectedCategory(e.target.value);
};
const handleInputChange = (e) => {
let { name, value } = e.target;
setFormValues({
...formValues,
[name]: value
});
};
async function handleCtrlClick(target) {
/// allow pasting the clipboard with just ctrl click
}
const handleClick = (event) => {
// In that case, event.ctrlKey does the trick.
if (event.ctrlKey) {
event.stopPropagation();
handleCtrlClick(event.target);
}
};
const myHandleSubmit = () => {
let arr = selectedCategory.split('^'); /// This trick allowed me to show the selected category name instead of the categoryId
setFormValues({
...formValues,
uploadDate: uploadDate,
categoryId: arr[0]
});
alert(JSON.stringify(formValues, null, 4));
};
const handleReset = () => {
/// resets all fields
};
return (
<form onSubmit={handleSubmit}>
<Box
component="form"
sx={{
'& > :not(style)': { m: 1, width: '30ch', marginTop: '50px', marginBottom: '0' }
}}
noValidate
autoComplete="off"
>
<Stack spacing={3}>
<TextField
…
/>
<TextField
…
/>
<TextField
…
/>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
id="author-uploadDate"
name="uploadDate"
label="Video UploadDate"
value={uploadDate}
defaultValues={uploadDate}
onChange={(newValue) => {
setUploadDate(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
</LocalizationProvider>
<TextField
…
/>
<FormControl sx={{ minWidth: 120, maxWidth: '500px', width: '270px' }}>
<InputLabel id="video categories">Video Category</InputLabel>
<Select
labelId="video categories"
id="simple-select"
value={selectedCategory}
label="Video Category"
onChange={handleCategoryChange}
>
{categories.map((category) => {
return (
<MenuItem value={category.id.toString() + '^' + category.name}>
{category.name}
</MenuItem>
);
})}
</Select>
</FormControl>
<TextField
…
/>
</Stack>
<Button variant="contained" endIcon={<SendIcon />} size="medium" onClick={myHandleSubmit}>
Submit
</Button>
<Button variant="outlined" startIcon={<DeleteIcon />} size="medium" onClick={handleReset}>
Reset
</Button>
</Box>
</form>
);
};
// title, origin, author, uploadDate, url, excerpt
const defaultValues = {
title: '',
origin: 'Vimeo',
author: '',
uploadDate: today(),
categoryId: 0,
url: '',
excerpt: ''
};
function mapStateToProps(state) {
…
}
function mapDispatchToProps(dispatch) {
…
}
export default connect(mapStateToProps, mapDispatchToProps)(AddVideoAndCategories);
Can somebody see why that happens?

Using Material UI's Autocomplete using Formik to display different value in dropdown but set different value in formik state

I am trying to use Material UI's Autocomplete with Formik. Here is a custom Autocomplete component I wrote to use with Formik.
import React from "react";
import Autocomplete from "#material-ui/lab/Autocomplete";
import TextField from "#material-ui/core/TextField";
import { fieldToTextField } from "formik-material-ui";
const FormikAutocomplete = ({ textFieldProps, ...props }) => {
const {
form: { setTouched, setFieldValue },
} = props;
const { error, helperText, ...field } = fieldToTextField(props);
const { name } = field;
return (
<Autocomplete
{...props}
{...field}
onChange={(_, value) =>
setFieldValue(name, value)
}
onBlur={() => setTouched({ [name]: true })}
renderInput={(props) => (
<TextField
{...props}
{...textFieldProps}
helperText={helperText}
error={error}
/>
)}
/>
);
};
export default FormikAutocomplete;
Here is how components callled
<Field
name="title"
component={FormikAutocomplete}
options={gender}
getOptionLabel={(option) => option.title_name_long}
textFieldProps={{
label: "Title",
required: true,
variant: "outlined",
margin: "dense",
}}
/>
Now what I intend to do is: If I have a object like
gender=[{gender_name_short:"F",gender_name_long:"Female},{gender_name_short:"M",gender_name_long:"Male}]
I want the Autocomplete dropdown to show options male,female.
But I want the formik state to save M,F respectively once selected from dropdown. Currently the entire object gets saved.
How can this be done?
In FormikAutocomplete component,
use setFieldValue in the onChange of autocomplete
use gender_name_long in getOptionLabel to display Male , Female
use gender_name_short in getOptionSelected to use M or F
With that, finally, when you submit, you will get to see M/F not Male/Female
Working demo
const gender = [
{ gender_name_short: "F", gender_name_long: "Female" },
{ gender_name_short: "M", gender_name_long: "Male" }
];
const validationSchema = object().shape({
// genderObj: array().required("At least one gender is required")
});
const initialValues = {
username: "abc",
country: "",
gender: "M",
birthdate: null
};
const FormikAutocomplete = ({ textFieldProps, ...props }) => {
const {
form: { setTouched, setFieldValue }
} = props;
const { error, helperText, ...field } = fieldToTextField(props);
const { name } = field;
return (
<Autocomplete
{...field}
{...props}
onChange={(_, data) => {
setFieldValue("gender", data.gender_name_short);
}}
onBlur={() => setTouched({ [name]: true })}
// getOptionLabel={item => item.gender_name_long} //<----see here
getOptionLabel={item => {
// console.log( '====>' , typeof item === "string" ? props.options.find(i => i.gender_name_short === item).gender_name_long : item.gender_name_long)
return typeof item === "string"
? props.options.find(i => i.gender_name_short === item)
.gender_name_long
: item.gender_name_long;
}}
// getOptionLabel={item => typeof item === 'string' ? props.options.find(i => i.gender_name_short === item).gender_name_long : item.gender_name_long}
getOptionSelected={(item, current) => {
return item.gender_name_short === current;
}}
// defaultValue={'hi'}
renderInput={props => (
<TextField
{...props}
{...textFieldProps}
helperText={helperText}
error={error}
/>
)}
/>
);
};
const SimpleFormExample = () => (
<div>
<h1>Simple Form Example</h1>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
validateOnBlur={false}
validateOnChange
onSubmit={(values, { resetForm, setSubmitting }) => {
console.log(values);
resetForm();
// setSubmitting(false);
}}
>
{formik => (
<Form>
<Field
name="gender"
component={FormikAutocomplete}
label="gender"
options={gender}
textFieldProps={{
fullWidth: true,
margin: "normal",
variant: "outlined"
}}
// multiple
/>
<button type="submit">Submit</button>
</Form>
)}
</Formik>
</div>
);
export default SimpleFormExample;

Material-UI Autocomplete onChange not updates value

I want to use onChange event on Autocomplete component to get current selected values.
The problem is that it does not working as expected, so when I click to check/uncheck value checkbox is still unchecked but in console i can see that new value was added
uncoment this part to make it works:
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
online demo:
https://codesandbox.io/embed/hardcore-snowflake-7chnc?fontsize=14&hidenavigation=1&theme=dark
code:
const [myTempVal, setMyTempVal] = React.useState([]);
<Autocomplete
open
multiple
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
You need to get donors receivers and options variables out of the function. Those variables get re-created at each render, this means that their reference changes at each render, and as Autocomplete makes a reference equality check to decide if an option is selected he never finds the options selected.
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
export const App = props => {
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
...
You can also add getOptionSelected to overwrite the reference check :
<Autocomplete
open
multiple
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
getOptionSelected={(option, value) => option.title === value.title}
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
This can help:
Replace
checked={selected}
To
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
The complete solution
import React from "react";
import "./styles.css";
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
import CheckBoxOutlineBlankIcon from "#material-ui/icons/CheckBoxOutlineBlank";
import CheckBoxIcon from "#material-ui/icons/CheckBox";
import Checkbox from "#material-ui/core/Checkbox";
import SearchIcon from "#material-ui/icons/Search";
const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
const checkedIcon = <CheckBoxIcon fontSize="small" />;
const data = [
{ donor: "Trader Joe's", receiver: "Person-to-Person" },
{ donor: "Trader Joe's", receiver: "Homes with Hope" },
{ donor: "Santa Maria", receiver: "Gillespie Center" },
{ donor: "Santa Maria", receiver: null }
];
export const App = props => {
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
value={myTempVal}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
onClick={
()=>{
if(myTempVal.filter(obj=>obj.title===option.title).length!==0){
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title)],console.log(myTempVal))
}else{
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title),option],console.log(myTempVal))
}
}
}
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
);
};
export default App;
It is bit late to Answer this question but it might help someone.
In your code you have added onChange event in Autocomplete. When you click on checkbox it will trigger 2 times, one for checkbox and one for Autocomplte. Hence 2nd time trigger makes again checkbox unchecked so u get value in console but still checkbox is empty.
You can remove your checkbox in renderOption and use checked and uncheked icon instaed of checkbox.
renderOption={(option, { selected }) => {
return (
<React.Fragment>
{selected ? <CheckedIcon> : <uncheckedIcon>}
<div>
{option.title}
</div>
</React.Fragment>
</>
);
}}

Downshift autocomplete onBlur resetting value with Formik

I have a form with a field that needs to show suggestions via an api call. The user should be allowed to select one of those options or not and that value that they type in gets used to submit with the form, but this field is required. I am using Formik to handle the form, Yup for form validation to check if this field is required, downshift for the autocomplete, and Material-UI for the field.
The issue comes in when a user decides not to use one of the suggested options and the onBlur triggers. The onBlur always resets the field and I believe this is Downshift causing this behavior but the solutions to this problem suggest controlling the state of Downshift and when I try that it doesn't work well with Formik and Yup and there are some issues that I can't really understand since these components control the inputValue of this field.
Heres what I have so far:
const AddBuildingForm = props => {
const [suggestions, setSuggestions] = useState([]);
const { values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
modalLoading,
setFieldValue,
setFieldTouched,
classes } = props;
const loadOptions = (inputValue) => {
if(inputValue && inputValue.length >= 3 && inputValue.trim() !== "")
{
console.log('send api request', inputValue)
LocationsAPI.autoComplete(inputValue).then(response => {
let options = response.data.map(erlTO => {
return {
label: erlTO.address.normalizedAddress,
value: erlTO.address.normalizedAddress
}
});
setSuggestions(options);
});
}
setFieldValue('address', inputValue); // update formik address value
}
const handleSelectChange = (selectedItem) => {
setFieldValue('address', selectedItem.value); // update formik address value
}
const handleOnBlur = (e) => {
e.preventDefault();
setFieldValue('address', e.target.value);
setFieldTouched('address', true, true);
}
const handleStateChange = changes => {
if (changes.hasOwnProperty('selectedItem')) {
setFieldValue('address', changes.selectedItem)
} else if (changes.hasOwnProperty('inputValue')) {
setFieldValue('address', changes.inputValue);
}
}
return (
<form onSubmit={handleSubmit} autoComplete="off">
{modalLoading && <LinearProgress/>}
<TextField
id="name"
label="*Name"
margin="normal"
name="name"
type="name"
onChange={handleChange}
value={values.name}
onBlur={handleBlur}
disabled={modalLoading}
fullWidth={true}
error={touched.name && Boolean(errors.name)}
helperText={touched.name ? errors.name : ""}/>
<br/>
<Downshift id="address-autocomplete"
onInputValueChange={loadOptions}
onChange={handleSelectChange}
itemToString={item => item ? item.value : '' }
onStateChange={handleStateChange}
>
{({
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
isOpen,
}) => (
<div>
<TextField
id="address"
label="*Address"
name="address"
type="address"
className={classes.autoCompleteOptions}
{...getInputProps( {onBlur: handleOnBlur})}
disabled={modalLoading}
error={touched.address && Boolean(errors.address)}
helperText={touched.address ? errors.address : ""}/>
<div {...getMenuProps()}>
{isOpen ? (
<Paper className={classes.paper} square>
{suggestions.map((suggestion, index) =>
<MenuItem {...getItemProps({item:suggestion, index, key:suggestion.label})} component="div" >
{suggestion.value}
</MenuItem>
)}
</Paper>
) : null}
</div>
</div>
)}
</Downshift>
<Grid container direction="column" justify="center" alignItems="center">
<Button id="saveBtn"
type="submit"
disabled={modalLoading}
className = {classes.btn}
color="primary"
variant="contained">Save</Button>
</Grid>
</form>
);
}
const AddBuildingModal = props => {
const { modalLoading, classes, autoComplete, autoCompleteOptions } = props;
return(
<Formik
initialValues={{
name: '',
address: '',
}}
validationSchema={validationSchema}
onSubmit = {
(values) => {
values.parentId = props.companyId;
props.submitAddBuildingForm(values);
}
}
render={formikProps => <AddBuildingForm
autoCompleteOptions={autoCompleteOptions}
autoComplete={autoComplete}
classes={classes}
modalLoading={modalLoading}
{...formikProps} />}
/>
);
}
Got it to work. Needed to use handleOuterClick and set the Downshift state with the Formik value:
const handleOuterClick = (state) => {
// Set downshift state to the updated formik value from handleOnBlur
state.setState({
inputValue: values.address
})
}
Now the value stays in the input field whenever I click out.

Resources