当通过逻辑更改检查值时,带有react-hook-form V7的Material-UI复选框不会发送正确的值

edu*_*arg 2 reactjs material-ui react-hook-form

我使用的是react-hook-form V7.14.2,并且使用的是Material-UI复选框,用户可以手动检查该复选框,也可以根据某些输入的值自动检查该复选框。这工作正常。

问题是,在提交表单时,如果通过逻辑选中复选框,则根据某些输入的值,发送到后端的值将为 false。如果用户手动选中该复选框,那么它将发送正确的值。-如果选中则为真-。

我在react-hook-form页面中阅读了从V6迁移到V7的文档,因为我之前使用的是V6并且代码在那里工作。 https://react-hook-form.com/migrate-v6-to-v7/

我还阅读了 Stackoverflow 中以前的一些答案,例如:material-ui checkbox with react-hook-form但没有成功。

这是我的代码:

import React, { useContext, useState, useEffect } from "react";
import Checkbox from "@material-ui/core/Checkbox";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheckCircle } from "@fortawesome/free-solid-svg-icons";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import { Controller, set } from "react-hook-form";
import { makeStyles } from "@material-ui/core/styles";
import { DarkThemeContext } from "../../context/DarkThemeContext";
import { useStylesSelectPropDetails } from "../../styledComponent/SelectPropDetailsStyled";
import { IMAGES_LINK } from "../../api/doFetch";

const useStylesLabel = makeStyles((theme) => ({
  label: {
    fontSize: "1em",
    fontFamily: "Open Sans Hebrew, sans-serif !important",
    fontWeight: 400,
    lineHeight: 1.5,
  },
}));

const CheckboxPropDetails = ({
  register,
  name,
  label,
  checked,
  isShelter,
  isElevator,
}) => {
  const classesLabel = useStylesLabel();
  const [isDarkTheme] = useContext(DarkThemeContext);
  const [isChecked, setIsChecked] = useState(false);
  const props = { isDarkTheme: isDarkTheme };
  const classes = useStylesSelectPropDetails(props);

  const handleChange = (event) => {
    setIsChecked(event.target.checked);
  };

  useEffect(() => {
    if (name === "shelter") {
      if (  isShelter,) {
        setIsChecked(true);
      } else setIsChecked(false);
    }
    if (name === "elevator") {
      console.log("elevator");

      if (isElevator) {
        console.log("isElevator", isElevator);
        setIsChecked(true);
      } else setIsChecked(false);
    }
  }, [  isShelter, isElevator]);

  return (
    <>
      <FormControlLabel
        classes={classesLabel}
        control={
          <Checkbox
            name={name}
            id={name}
            defaultChecked={checked ? checked : false}
            {...register(name)}
            color="primary"
            size={"medium"}
            icon={
              <img
                src={`${IMAGES_LINK}/dashboard/elements/rec.svg`}
                alt="Circle"
                style={{ width: 20, height: 20 }}
              />
            }
            disableRipple
            checkedIcon={
              <FontAwesomeIcon
                icon={faCheckCircle}
                style={{ width: 20, height: 20 }}
              />
            }
            checked={isChecked}
            onChange={(e) => handleChange(e)}
          />
        }
        labelPlacement="end"
        label={<p className={classes.paragraphAddProp}>{label}</p>}
      />
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

在react-hook-form上与V6一起使用的代码:

import React, { useContext, useState, useEffect } from "react";
import Checkbox from "@material-ui/core/Checkbox";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheckCircle } from "@fortawesome/free-solid-svg-icons";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import { Controller } from "react-hook-form";
import { makeStyles } from "@material-ui/core/styles";
import { DarkThemeContext } from "../../context/DarkThemeContext";
import { useStylesSelectPropDetails } from "../../styledComponent/SelectPropDetailsStyled";
import { IMAGES_LINK } from "../../api/doFetch";

const useStylesLabel = makeStyles((theme) => ({
  label: {
    fontSize: "1em",
    fontFamily: "Open Sans Hebrew, sans-serif !important",
    fontWeight: 400,
    lineHeight: 1.5,
  },
}));

const CheckboxPropDetails = ({
  register,
  name,
  label,
  checked,
  isShelter,
  isElevator,
}) => {
  const classesLabel = useStylesLabel();
  const [isDarkTheme] = useContext(DarkThemeContext);
  const props = { isDarkTheme: isDarkTheme };
  const classes = useStylesSelectPropDetails(props);
  const [isChecked, setIsChecked] = useState(false);

  const handleChange = (event) => {
    console.log("event", event.target.checked);
    setIsChecked(event.target.checked);
  };

  useEffect(() => {
    if (name === "shelter") {
      if (isShelter) {
        setIsChecked(true);
      } else setIsChecked(false);
    }
    if (name === "elevator") {   
      if (isElevator) {
           setIsChecked(true);
      } else setIsChecked(false);
    }
  }, [isShelter, isElevator]);

  return (
    <>
      <FormControlLabel
        classes={classesLabel}
        control={
          <Checkbox
            name={name}
            defaultChecked={checked ? checked : false}
            inputRef={register}
            color="primary"
            size={"medium"}
            icon={
              <img
                src={`${IMAGES_LINK}/dashboard/elements/rec.svg`}
                alt="Circle"
                style={{ width: 20, height: 20 }}
              />
            }
            disableRipple
            checkedIcon={
              <FontAwesomeIcon
                icon={faCheckCircle}
                style={{ width: 20, height: 20 }}
              />
            }
            checked={isChecked}
            onChange={(e) => handleChange(e)}
          />
        }
        labelPlacement="end"
        label={<p className={classes.paragraphAddProp}>{label}</p>}
      />
    </>
  );
};
Run Code Online (Sandbox Code Playgroud)

控制、注册等都作为 props 从另一个组件传递。

正如之前提到的,它在 V6 上运行。V6和V7的区别就一行:

在V6中

  inputRef={register}
Run Code Online (Sandbox Code Playgroud)

在V7中

  {...register(name)}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点,以便当通过逻辑更改检查的值时,它将注册并在提交时将作为 true 发送到后端?

kno*_*fel 10

MUI<Checkbox />组件用于设置value. RHF 值必须使用checkedprop 设置。

在 v6 中,您刚刚传递registerinputRef,但由于 v7 调用register将返回一个对象 - 该对象的两个属性是valueonChange。因此,当将调用扩展register到 MUI时<Checkbox />,您将实际值的链接设置为valueprop,而不是使用checkedprop。

因此,您应该使用 RHF 的组件,查看此处的<Controller />文档以获取有关集成外部受控组件的更多信息。

<FormControlLabel
  control={
    <Controller
      name="checkbox"
      control={control}
      defaultValue={false}
      render={({ field: { value, ref, ...field } }) => (
        <Checkbox
          {...field}
          inputRef={ref}
          checked={!!value}
          color="primary"
          size={"medium"}
          disableRipple
        />
      )}
    />
  }
  label="Checkbox"
  labelPlacement="end"
/>
Run Code Online (Sandbox Code Playgroud)

一个重要的注意事项:您必须设置值 ,以避免在您的for最初为checked={!!value}时出现有关将组件从不受控更改为受控的警告。defaultValuesomeCheckboxundefined

编辑 React Hook 表单 - 基本(分叉)