Material-UI 带有 react-hook-form V7 的复选框在通过逻辑更改检查值时不会发送正确的值
Material-UI checkbox with react-hook-form V7 won't sent correct value when the cheked value is changed via logic
我使用的是 react-hook-form V7.14.2,我使用的是 Material-UI 复选框,可以由用户手动选中或自动选中,具体取决于某些输入的值。
这工作正常。
问题是在提交表单时,如果通过逻辑选中复选框,根据特定输入的值,发送到后端的值将为 false。
如果用户手动选中复选框,那么它将发送正确的值。 -如果选中则为真-.
我在 react-hook-form 页面中阅读了从 V6 迁移到 V7 的文档,因为我之前使用的是 V6 并且代码在那里工作。
https://react-hook-form.com/migrate-v6-to-v7/
我也在 Whosebug 中阅读了一些以前的答案,例如这个: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>}
/>
</>
);
};
在 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>}
/>
</>
);
};
控制、注册等正在作为道具从另一个组件传递。
如前所述,它在 V6 上运行。
V6和V7的区别只有一行:
在 V6 中
inputRef={register}
在 V7 中
{...register(name)}
我怎样才能做到这一点,以便当通过逻辑更改选中的值时,它将注册并在提交时将其作为 true 发送到后端?
MUI <Checkbox />
组件在设置 value
时的界面略有不同。 RHF 值必须使用 checked
属性设置。
在 v6 中,您只是将 register
传递给了 inputRef
,但是由于 v7 调用 register
将 return 一个对象 - 这个对象的两个属性是 value
和 onChange
。因此,当将 register
调用扩展到 MUI <Checkbox />
时,您将实际值的 link 设置为 value
道具,而不是使用 checked
道具.
因此您应该使用 RHF 的 <Controller />
组件,查看文档 here 以获取有关集成外部受控组件的更多信息。
<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"
/>
一个重要提示:您必须使用 checked={!!value}
设置值,以避免在您的 defaultValue
for someCheckbox
最初是undefined
.
我使用的是 react-hook-form V7.14.2,我使用的是 Material-UI 复选框,可以由用户手动选中或自动选中,具体取决于某些输入的值。 这工作正常。
问题是在提交表单时,如果通过逻辑选中复选框,根据特定输入的值,发送到后端的值将为 false。 如果用户手动选中复选框,那么它将发送正确的值。 -如果选中则为真-.
我在 react-hook-form 页面中阅读了从 V6 迁移到 V7 的文档,因为我之前使用的是 V6 并且代码在那里工作。 https://react-hook-form.com/migrate-v6-to-v7/
我也在 Whosebug 中阅读了一些以前的答案,例如这个: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>}
/>
</>
);
};
在 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>}
/>
</>
);
};
控制、注册等正在作为道具从另一个组件传递。
如前所述,它在 V6 上运行。 V6和V7的区别只有一行:
在 V6 中
inputRef={register}
在 V7 中
{...register(name)}
我怎样才能做到这一点,以便当通过逻辑更改选中的值时,它将注册并在提交时将其作为 true 发送到后端?
MUI <Checkbox />
组件在设置 value
时的界面略有不同。 RHF 值必须使用 checked
属性设置。
在 v6 中,您只是将 register
传递给了 inputRef
,但是由于 v7 调用 register
将 return 一个对象 - 这个对象的两个属性是 value
和 onChange
。因此,当将 register
调用扩展到 MUI <Checkbox />
时,您将实际值的 link 设置为 value
道具,而不是使用 checked
道具.
因此您应该使用 RHF 的 <Controller />
组件,查看文档 here 以获取有关集成外部受控组件的更多信息。
<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"
/>
一个重要提示:您必须使用 checked={!!value}
设置值,以避免在您的 defaultValue
for someCheckbox
最初是undefined
.