Im Learning ReactJs ... I want Design a Form (Like Section Exprience in Linkedin) with React Hook Form, Material Ui and TypeScript.
I Faced a Error with this text: 'onChange' is specified more than once, so this usage will be overwritten.
my function in onChange, doesn't work. I want to register with react hook form. how can I solve this error?
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Box from "@mui/material/Box";
import { React, useState } from "react";
import { useForm, SubmitHandler } from "react-hook-form";
import Divider from "@mui/material/Divider";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import InputLabel from "@mui/material/InputLabel";
// React Hook Form Types
type Inputs = {
title: string;
employment: string;
company: string;
location: string;
startDate: string;
endDate: string;
description: string;
};
function ExprienceCreate() {
const [employment, setEmployment] = useState("");
// React Hook Form
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm<Inputs>();
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data);
// Function For Employment Type Select
const handleChange = (event: SelectChangeEvent) => {
setEmployment(event.target.value as string);
console.log(employment);
};
console.log(watch("title")); // watch input value by passing the name of it
return (
<Box
sx={{
width: "414px",
border: "1px solid #000",
p: 2,
borderRadius: 1,
margin: "16px auto",
}}
>
<form onSubmit={handleSubmit(onSubmit)}>
<Typography sx={{ my: "12px" }}>Title:</Typography>
<TextField
placeholder="Ex: Sales Manager"
fullWidth
{...register("title")}
sx={{ mb: 2 }}
></TextField>
<Divider />
<Typography sx={{ my: "12px" }}>Employment type:</Typography>
<InputLabel id="demo-simple-select-label">Employment Type</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={employment}
label="Employment Type"
onChange={handleChange}
{...register("employment")}
sx={{ mb: 2, width: "100%" }}
>
<MenuItem value={"full"}>FullTime</MenuItem>
<MenuItem value={"part"}>PartTime</MenuItem>
</Select>
<Divider />
<Typography sx={{ my: "12px" }}>Company name:</Typography>
<TextField
placeholder="Ex: Microsoft"
fullWidth
{...register("company")}
sx={{ mb: 2 }}
></TextField>
<Divider />
<Typography sx={{ my: "12px" }}>Location:</Typography>
<TextField
placeholder="Ex: London, United Kingdom"
fullWidth
{...register("location")}
sx={{ mb: 2 }}
></TextField>
<Divider />
<Typography sx={{ my: "12px" }}>Date:</Typography>
<TextField
placeholder="Ex: Sales Manager"
fullWidth
{...register("startDate")}
sx={{ mb: 2 }}
></TextField>
<TextField
placeholder="Ex: Sales Manager"
fullWidth
{...register("endDate")}
sx={{ mb: 2 }}
></TextField>
<Divider />
<Typography sx={{ my: "12px" }}>Description:</Typography>
<TextField
fullWidth
{...register("description")}
sx={{ mb: 2 }}
></TextField>
</form>
</Box>
);
}
export default ExprienceCreate;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
CodePudding user response:
Unfortunately Anastasia's answer is not correct, because that way you will overwrite react-hook-form
's onChange
- so this will it prevent from updating it's internal form state and therefore the current value won't be available in your onSubmit
callback.
If you need to have an onChange
callback for register
you can provide a callback in the config options, which you can pass a second argument. Check the docs for more infos.
But i guess the useState
for the "employment" field is not needed here as you could just access the current value in your onSubmit
callback. If you need to access it before submitting then you could use watch
as you did with the "title" field.
Using onChange
config option
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
label="Employment Type"
{...register("employment", { onChange: handleChange })}
sx={{ mb: 2, width: "100%" }}
>
Using watch
const employment = watch('employment');
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
label="Employment Type"
{...register("employment")}
sx={{ mb: 2, width: "100%" }}
>
CodePudding user response:
register
probably overwrites the onChange
you have specified. Try swapping the order of onChange
and register
.
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={employment}
label="Employment Type"
{...register("employment")}
onChange={handleChange}
sx={{ mb: 2, width: "100%" }}
>