是的,有条件地使用 `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