最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to validate React-quill with React-hook-form and yup? - Stack Overflow

programmeradmin3浏览0评论

I used

  • react-quill for one of form element.
  • react-hook-form form validation
  • yup/yup resolver for validation schema

Normal inputs and textareas working as expected, but validation for react-quill is not working.

These are my code snippets.

Custom react-quill wrapper element

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 / for plete 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 /
 */
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;

This is form ponent

const validationSchema = Yup.object().shape({
    panyName: 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"
                  />
                )}
              />

I checked these issues,

but still not working.

Current behavior

I confirmed the changed markdown logged in console (onChange function in Editor), but can't see formState log of useEffect hook upon editor change. (regardless of add rules prop to Controller or not)

Any help would be much appreciated

Thank you

I used

  • react-quill for one of form element.
  • react-hook-form form validation
  • yup/yup resolver for validation schema

Normal inputs and textareas working as expected, but validation for react-quill is not working.

These are my code snippets.

Custom react-quill wrapper element

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./docs/modules/ for plete 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./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;

This is form ponent

const validationSchema = Yup.object().shape({
    panyName: 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"
                  />
                )}
              />

I checked these issues, https://github./zenoamaro/react-quill/issues/635

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

but still not working.

Current behavior

I confirmed the changed markdown logged in console (onChange function in Editor), but can't see formState log of useEffect hook upon editor change. (regardless of add rules prop to Controller or not)

Any help would be much appreciated

Thank you

Share Improve this question asked Jun 15, 2021 at 9:32 Forest1206Forest1206 731 gold badge1 silver badge10 bronze badges 3
  • What is the current behavior? what is it doing? – Nemo Commented Jun 18, 2021 at 0:47
  • I have never used formState but first thing first, is this code in the form tag? – Nemo Commented Jun 18, 2021 at 0:52
  • sure, it's in form tag. – Forest1206 Commented Jun 18, 2021 at 12:56
Add a ment  | 

3 Answers 3

Reset to default 8
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>
  );
}

I have created a code sandbox with a working example for react-hook-form. Here is the link:

https://codesandbox.io/s/quill-with-react-hook-form-validation-cdjru
<Controller
  name="desc"
  control={control}
  rules={{
    required: "Please enter task description",
  }}
  theme="snow"
  modules={modules}
  render={({ field }) => (
    <ReactQuill
      {...field}
      placeholder={"Write Description"}
      onChange={(text) => {
        field.onChange(text);
      }}
    />
  )}
/>;

You Can Add Validator As ur like

you can try with "react-hook-form"

  <FormField
            control={form.control}
            name="content"
            render={({ field }) => (
              <FormItem>
                <FormLabel className="text-white">Picture</FormLabel>
                <FormControl>
                  <ReactQuill
                    {...field}
                    ref={quillRef}
                    modules={modules}
                    theme="snow"
                    placeholder={"Write Description"}
                    className="mt-4 text-white"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />




export const PostSchema: z.ZodType<PostType> = z.object({
  id: z.number(),
  shortDesc: z.string().min(4, "Minumun 4 in legnth"),
});
发布评论

评论列表(0)

  1. 暂无评论