是的,有条件地使用 `when` 和无线电输入
Yup conditional using `when` with radio inputs
我不确定我做错了什么(可能是一些愚蠢的事情)。我将 React Hook Form 与 Yup 一起使用,并尝试根据检查无线电组的方式设置条件。
基本上,如果您检查第一个 单选,则只需要一个 字段。
但是,如果您选中 second 单选按钮,则需要 both 个文本字段。
我想我搞砸了 validationSchema
但我没看到它。
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import "./styles.css";
export default function App() {
const validationSchema = yup.object().shape({
decide: yup.string(),
one: yup.string().required(),
two: yup.string().when("decide", {
is: "decideBoth",
then: yup.string().required(),
otherwise: yup.string().notRequired()
})
});
const { register, handleSubmit, errors } = useForm({ validationSchema });
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
const { value } = event.target;
setDecide(value);
}
const [decide, setDecide] = useState("decideOne");
return (
<div className="App">
<form onSubmit={handleSubmit(console.log)}>
<div>
<input
type="radio"
name="decide"
id="decideOne"
value="decideOne"
checked={decide === "decideOne"}
onChange={handleChange}
/>
<label htmlFor="decideOne">only one required</label>
<input
type="radio"
name="decide"
id="decideBoth"
value="decideBoth"
checked={decide === "decideBoth"}
onChange={handleChange}
/>
<label htmlFor="decideBoth">both required</label>
</div>
<div>
<label htmlFor="one">one</label>
<input ref={register} type="text" name="one" />
{errors.one && <p>{errors.one.message}</p>}
</div>
<div>
<label htmlFor="two">two</label>
<input ref={register} type="text" name="two" />
{errors.two && <p>{errors.two.message}</p>}
</div>
<button type="submit">submit</button>
</form>
</div>
);
}
这里是link到https://codesandbox.io/s/musing-beaver-dce80?file=/src/App.tsx
您需要将 register
传递给 ref
单选按钮的回调。
这是工作代码。另外,我为 decide
删除了 useState
,因为它将由 react-hook-form
.
处理
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import "./styles.css";
export default function App() {
const validationSchema = yup.object().shape({
decide: yup.string(),
one: yup.string().required(),
two: yup.string().when("decide", (val, schema) => {
console.log("when", val);
if (val === "decideBoth") return yup.string().required();
else return yup.string().notRequired();
})
});
const { register, handleSubmit, errors, getValues } = useForm({
validationSchema,
defaultValues: {
decide: "decideOne"
}
});
const onSubmit = (data) => {
console.log("On Submit", data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<input
ref={register}
type="radio"
name="decide"
id="decideOne"
value="decideOne"
defaultChecked={getValues("decide") === "decideOne"}
// onChange={handleChange}
/>
<label htmlFor="decideOne">only one required</label>
<input
ref={register}
type="radio"
name="decide"
id="decideBoth"
value="decideBoth"
defaultChecked={getValues("decide") === "decideBoth"}
// onChange={handleChange}
/>
<label htmlFor="decideBoth">both required</label>
</div>
<div>
<label htmlFor="one">one</label>
<input ref={register} type="text" name="one" />
{errors.one && <p>{errors.one.message}</p>}
</div>
<div>
<label htmlFor="two">two</label>
<input ref={register} type="text" name="two" />
{errors.two && <p>{errors.two.message}</p>}
</div>
<button type="submit">submit</button>
</form>
</div>
);
}
这里是沙盒:https://codesandbox.io/s/distracted-jackson-l14hj?file=/src/App.tsx
我不确定我做错了什么(可能是一些愚蠢的事情)。我将 React Hook Form 与 Yup 一起使用,并尝试根据检查无线电组的方式设置条件。
基本上,如果您检查第一个 单选,则只需要一个 字段。 但是,如果您选中 second 单选按钮,则需要 both 个文本字段。
我想我搞砸了 validationSchema
但我没看到它。
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import "./styles.css";
export default function App() {
const validationSchema = yup.object().shape({
decide: yup.string(),
one: yup.string().required(),
two: yup.string().when("decide", {
is: "decideBoth",
then: yup.string().required(),
otherwise: yup.string().notRequired()
})
});
const { register, handleSubmit, errors } = useForm({ validationSchema });
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
const { value } = event.target;
setDecide(value);
}
const [decide, setDecide] = useState("decideOne");
return (
<div className="App">
<form onSubmit={handleSubmit(console.log)}>
<div>
<input
type="radio"
name="decide"
id="decideOne"
value="decideOne"
checked={decide === "decideOne"}
onChange={handleChange}
/>
<label htmlFor="decideOne">only one required</label>
<input
type="radio"
name="decide"
id="decideBoth"
value="decideBoth"
checked={decide === "decideBoth"}
onChange={handleChange}
/>
<label htmlFor="decideBoth">both required</label>
</div>
<div>
<label htmlFor="one">one</label>
<input ref={register} type="text" name="one" />
{errors.one && <p>{errors.one.message}</p>}
</div>
<div>
<label htmlFor="two">two</label>
<input ref={register} type="text" name="two" />
{errors.two && <p>{errors.two.message}</p>}
</div>
<button type="submit">submit</button>
</form>
</div>
);
}
这里是link到https://codesandbox.io/s/musing-beaver-dce80?file=/src/App.tsx
您需要将 register
传递给 ref
单选按钮的回调。
这是工作代码。另外,我为 decide
删除了 useState
,因为它将由 react-hook-form
.
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import * as yup from "yup";
import "./styles.css";
export default function App() {
const validationSchema = yup.object().shape({
decide: yup.string(),
one: yup.string().required(),
two: yup.string().when("decide", (val, schema) => {
console.log("when", val);
if (val === "decideBoth") return yup.string().required();
else return yup.string().notRequired();
})
});
const { register, handleSubmit, errors, getValues } = useForm({
validationSchema,
defaultValues: {
decide: "decideOne"
}
});
const onSubmit = (data) => {
console.log("On Submit", data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<input
ref={register}
type="radio"
name="decide"
id="decideOne"
value="decideOne"
defaultChecked={getValues("decide") === "decideOne"}
// onChange={handleChange}
/>
<label htmlFor="decideOne">only one required</label>
<input
ref={register}
type="radio"
name="decide"
id="decideBoth"
value="decideBoth"
defaultChecked={getValues("decide") === "decideBoth"}
// onChange={handleChange}
/>
<label htmlFor="decideBoth">both required</label>
</div>
<div>
<label htmlFor="one">one</label>
<input ref={register} type="text" name="one" />
{errors.one && <p>{errors.one.message}</p>}
</div>
<div>
<label htmlFor="two">two</label>
<input ref={register} type="text" name="two" />
{errors.two && <p>{errors.two.message}</p>}
</div>
<button type="submit">submit</button>
</form>
</div>
);
}
这里是沙盒:https://codesandbox.io/s/distracted-jackson-l14hj?file=/src/App.tsx