In my React Typescript app, there is a Formik form with fields that does not need to be populated with any values (i.e. the placeholder text is visible).
How can we achieve this?
Attempt 1:
In Formik's initialValues
, I tried not defining any values whose form should be empty initially.
<Formik
initialValues={{
itemType: 'any',
}}
...
>
interface Values {
itemType: string;
minPrice?: number;
maxPrice?: number;
}
However, when a user types something into any of these forms, the browser JS console shows the warning:
index.js:1 Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components at input
Attempt 2:
Tried setting these values to null
in Formik's initialValues
prop,
<Formik
initialValues={{
itemType: 'any',
minPrice: null,
maxPrice: null,
}}
...
but TypeScript throws an error:
Type 'string' is not assignable to type 'never'. TS2322
Type 'string' is not assignable to type 'never'. TS2322
66 | <Formik
67 | initialValues={{
> 68 | itemType: 'any',
| ^
69 | minPrice: null,
The React app does not even start!
Full Code
import { Button, Modal, Form, Row, Col } from 'react-bootstrap';
import { Formik, FormikHelpers } from 'formik';
interface Values {
itemType?: string;
minPrice?: number;
maxPrice?: number;
}
export function FormModal({show, handleClose, updateFilter}: IModal): JSX.Element {
return (
<Modal show={show} onHide={handleClose}>
<Modal.Body>
<Formik
initialValues={{
itemType: 'any',
minPrice: null,
maxPrice: null,
}}
validationSchema={schema}
onSubmit={(
values: Values,
) => {
updateFilter(values);
handleClose();
}}
>
{( {values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, setFieldValue }) => (
<Form id="updateFilterForm" onSubmit={handleSubmit}>
<Form.Group as={Row} controlId="formItemType">
<Form.Label column sm="3">Item Type</Form.Label>
<Col sm="9">
<Select
name="itemType"
options={itemTypeOptions}
onChange={option => setFieldValue("itemType", option!.value)}
onBlur={handleBlur}
values={values.itemType}
/>
</Col>
</Form.Group>
<Form.Group as={Row} controlId="formPrice">
<Form.Label column sm="3">Price Range</Form.Label>
<Col sm="9">
<Form.Row>
<Col>
<Form.Control
type="number"
name="minPrice"
onChange={handleChange}
onBlur={handleBlur}
value={values.minPrice}
placeholder="Min"
/>
</Col>
<Col>
<Form.Control
type="number"
name="maxPrice"
onChange={handleChange}
onBlur={handleBlur}
value={values.maxPrice}
placeholder="Max"
/>
</Col>
</Form.Row>
</Col>
</Form.Group>
</Form>
)}
</Formik>
</Modal.Body>
</Modal>
)
}