I’m using the combination of MUI + React Hook Form, so I’ve created a CustomTextField.tsx
component to make it worked.
// CustomTextField.tsx import { TextField } from "@mui/material"; export default function CustomTextField(props: any) { return ( <Controller name={props.name} control={props.control} render={({ field: { onChange, value }, fieldState: { error }, formState }) => <TextField onChange={onChange} {...props} />} /> ); }
Then at the app/parent level, I want to these steps:
- Fetch data and display to the TextField.
- Modify the text in TextField
- Submit the new value in TextField
This is my approach:
//App.tsx export default function App() { const { control, handleSubmit } = useForm(); const [fetchedData, setFetchedData] = useState<string>(""); ... return ( ... <CustomTextField control={control} name="description" label="Description" type="text" variant="outlined" value={fetchedData ? fetchedData: ""} //<-- fetched data is set to value of TextField to display /> ... ); }
With this approach, I managed to display the fetchedData
on TextField UI, but can not modify that data on text field. Also when I submit, the data is not correct to what display on the TextField
I have created a codesandbox link for this: https://codesandbox.io/s/blissful-sanne-x858dx?file=/src/App.tsx:190-1155
How can I display the fetchedData, but also can modify the data in text field and then submit through React Hook Form later?
Advertisement
Answer
Inspired by @Linda solution, I’ve came up with this approach, that ensures the functionality working with the style of MUI TextField as well.
The setValue
will be passed down to custom TextField to set the value. And to keep the {...props}
functionality, I delete the setValue
props before spreading it on MUI TextField.
//CustomTextField.tsx import { TextField } from "@mui/material" import { Controller } from "react-hook-form" export default function CustomTextField(props: any) { const propsObj = { ...props } delete propsObj.setValue return ( <Controller name={props.name} control={props.control} defaultValue={""} render={({ field: { onChange, value }, fieldState: { error }, formState, }) => ( <TextField value={value} onChange={({ target: { value } }) => { onChange(value) if (props?.setValue) props.setValue(props.name, value) }} {...propsObj} /> )} /> ) }
//App.tsx export default function App(){ const { control, handleSubmit, setValue } = useForm() return ( <form onSubmit={handleSubmit(...)}> <CustomTextField control={control} name="description" label="Description" type="text" variant="outlined" setValue={setValue} /> <form/> ) }