React hook form two inputs with same register key

Viewed 165

Have simple form with two almost identical inputs. One with range slider, another with input type number. Components from MUI library.

import Slider from "@mui/material/Slider";
import MuiInput from "@mui/material/Input";
import { useForm } from "react-hook-form";
//...

const { handleSubmit, register, control, } = useForm<{
    level: number;
}>({
    defaultValues: {
        level: 1,
    },
});

const [numberInput, setNumberInput] = useState<number>(5);

const handleNumberInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNumberInput(e.target.valueAsNumber);
};

const handleSliderChange = (event: Event, value: number | number[], activeThumb: number) => {
    setNumberInput(value as number);
};


<Slider
    {...register("level")}
    valueLabelDisplay="auto"
    step={1}
    min={1}
    max={20}
    marks={gameComplexityLevels}
    value={numberInput}
    onChange={handleSliderChange}
/>
<MuiInput
    size="small"
    {...register("level")}
    onChange={handleNumberInputChange}
    inputProps={{
        step: 1,
        min: 0,
        value: numberInput,
        max: 20,
        type: "number",
        "aria-labelledby": "input-slider",
    }}
/>

User can change same value from Slider either MuiInput component. The problem is that react-hook-form does not allow keys with same name.

{...register("level")}

This line is duplicating. Also, the inputs does not work correctly. When I remove register line, everything works as expected. But with register line components work unstable. Does anyone know a solution for this?

1 Answers

Would you please try this, you can set the value using setValue react-hook-form prop, you can see the docs from this link, and you can get the level value from getValue like getValue('level')

import Slider from "@mui/material/Slider";
import MuiInput from "@mui/material/Input";
import { useForm } from "react-hook-form";
//...

const { handleSubmit, register, control, setValue} = useForm<{
    level: number;
}>({
    defaultValues: {
        level: 1,
    },
});

const [numberInput, setNumberInput] = useState<number>(5);

const handleNumberInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setNumberInput(e.target.valueAsNumber);
    setValue("level", e.target.valueAsNumber);
};

const handleSliderChange = (event: Event, value: number | number[], activeThumb: number) => {
    setNumberInput(value as number);
    setValue("level", value as number);
};


<Slider
    valueLabelDisplay="auto"
    step={1}
    min={1}
    max={20}
    marks={gameComplexityLevels}
    value={numberInput}
    onChange={handleSliderChange}
/>
<MuiInput
    size="small"
    onChange={handleNumberInputChange}
    inputProps={{
        step: 1,
        min: 0,
        value: numberInput,
        max: 20,
        type: "number",
        "aria-labelledby": "input-slider",
    }}
/>
Related