javascript - 如何使用 React-hook-form 和 yup 验证 React-q

我用过

  • react-quill 用于表单元素之一。
  • react-hook-form 表单验证
  • yup/yup 验证模式解析器

正常输入和文本区域按预期工作,但 react-quill 验证不工作。

这些是我的代码片段。

自定义 react-quill 包装器元素

import React, { useRef, useState } from "react";
import PropTypes from "prop-types";
import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";
import "react-quill/dist/quill.bubble.css";
import "react-quill/dist/quill.core.css";

function Editor(props) {
  const [theme, setTheme] = useState("snow");
  const { id, value, inputRef, placeholder, onChange } = props;

  return (
    <ReactQuill
      id={id}
      ref={inputRef}
      theme={theme}
      onChange={onChange}
      value={value}
      modules={{
        toolbar: {
          ...Editor.modules.toolbar,
          handlers: {
            //   image: handleImageUpload,
          },
        },
        ...Editor.modules,
      }}
      formats={Editor.formats}
      bounds={".app"}
      placeholder={placeholder ?? ""}
    />
  );
}

/*
 * Quill modules to attach to editor
 * See https://quilljs.com/docs/modules/ for complete options
 */
Editor.modules = {
  toolbar: [
    // [{ header: '1' }, { header: '2' }, { font: [] }],
    // [{ size: [] }],
    [{ size: ["small", false, "large", "huge"] }], // custom dropdown
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [
      { list: "ordered" },
      { list: "bullet" },
      { indent: "-1" },
      { indent: "+1" },
    ],
    ["link", "image", "video"],
    ["clean"],
    [{ color: [] }, { background: [] }], // dropdown with defaults from theme
    [{ font: [] }],
    [{ align: [] }],
  ],
  clipboard: {
    // toggle to add extra line breaks when pasting HTML:
    matchVisual: false,
  },
};
/*
 * Quill editor formats
 * See https://quilljs.com/docs/formats/
 */
Editor.formats = [
  "header",
  "font",
  "size",
  "bold",
  "italic",
  "underline",
  "strike",
  "blockquote",
  "list",
  "bullet",
  "indent",
  "link",
  "image",
  "video",
];

/*
 * PropType validation
 */
Editor.propTypes = {
  placeholder: PropTypes.string,
};

export default Editor;

这是表单组件

const validationSchema = Yup.object().shape({
    companyName: Yup.string().required("Company Name is required"),
    ... ...

    jobDescription: Yup.string().required("Job description is required"), // react-quill

    ... ...
    howtoApply: Yup.string().required("This field is required"),
    applyUrl: Yup.string().required("This field is required"),
    applyEmail: Yup.string().required("This field is required"),

  });

const formOptions = { resolver: yupResolver(validationSchema) };

const { register, handleSubmit, reset, control, formState } = useForm(
    formOptions
  );

  useEffect(() => {
    console.log("formState", formState); // log for form value changes
  });


    ... ... ...

<Controller
                control={control}
                name="jobDescription"
                // rules={{
                //   required: "Description must have some content.",
                //   validate: (value) => {
                //     console.log("Controller", value);
                //     return (
                //       value.split(" ").length > 10 ||
                //       "Enter at least 10 words in the body."
                //     );
                //   },
                // }}
                render={({
                  field: { onChange, onBlur, value, name, ref },
                  fieldState: { invalid, isTouched, isDirty, error },
                  formState,
                }) => (
                  <Editor
                    onChange={(description, delta, source, editor) => {
                      console.log(
                        "onChange:description",
                        description,
                      );
                      console.log("inputRef", ref);
                      onChange(description);
                    }}
                    value={value || ""}
                    inputRef={ref}
                    theme="snow"
                    id="jobDescription"
                  />
                )}
              />

我检查了这些问题, https://github.com/zenoamaro/react-quill/issues/635

https://github.com/react-hook-form/react-hook-form/discussions/3372

但还是不行。

当前行为

我确认更改的 markdown 已登录到控制台(编辑器中的 onChange 函数),但在编辑器更改时看不到 useEffect Hook 的 formState 日志。 (无论是否向 Controller 添加规则 Prop )

任何帮助将不胜感激

谢谢

最佳答案

export default function App() {
  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors }
  } = useForm();

  useEffect(() => {
    register("emailContent", { required: true, minLength: 15 });
  }, [register]);

  const onEditorStateChange = (editorState) => {
    setValue("emailContent", editorState);
  };

  const onSubmit = (data) => {
    console.log(data);
  };

  const editorContent = watch("emailContent");

  return (
    <div className="App">
      <ReactQuill
        theme="snow"
        value={editorContent}
        onChange={onEditorStateChange}
      />
      <p className="Error">{errors.emailContent && "Enter valid content"}</p>
      <input type="submit" onClick={handleSubmit(onSubmit)} />
    </div>
  );
}

我已经创建了一个代码沙箱,其中包含一个用于 react-hook-form 的工作示例。这是链接:

https://codesandbox.io/s/quill-with-react-hook-form-validation-cdjru

关于javascript - 如何使用 React-hook-form 和 yup 验证 React-quill?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67983695/

相关文章:

bash - 如何压缩和忽略 .gitignore 指定的所有文件

python - 如何使 spaCy 匹配不区分大小写

javascript - 如何在 Vue 3 模板中使用导入函数?

algorithm - 斐波那契 : non-recursive vs memoized recur

vue.js - vue.config.js 中的 Vue devServer.proxy 不工作

SQL - Like and greater than 函数

javascript - 如何使用 Manifest v3 获取当前选项卡 URL?

python - 在python中获取每个月的最后一个星期五

java - 刀柄不同步

.net-core - 指定的 deps.json[] 不存在 - Blazor WebAssemb