Home > Back-end >  'onChange' is specified more than once, so this usage will be overwritten
'onChange' is specified more than once, so this usage will be overwritten

Time:03-02

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%" }}
    >
  • Related