0

我正在使用 react-hook-form 和 react-draft-wysiwyg。用户应该编辑和保存带有 html 字符串的元素。

控制器延迟传递道具,因此它传递未定义(第一次单击元素时)或先前值(第二次单击时)而不是正确的值。

对于第一种情况,我找到了一些解决方法(见评论),但仍然存在第二种情况。

如何立即通过适当的道具使其工作?

import React from "react";
import { Controller, UseFormMethods } from "react-hook-form";
import { WYSIWYGEditor } from "./wysiwyg-editor.component";

type Props = {
  name: string;
  control: UseFormMethods["control"];
};
export function RichTextWysiwyg(props: Props) {
  return (
    <Controller
      name={props.name}
      control={props.control}
      render={(event: any) => {
        //somehow props is not immediately passed to WYSIWYGEditor component so I added the condition below
        if (event.value !== undefined) {
          return <WYSIWYGEditor value={event.value} onChange={event.onChange} />
        }
        return <div/>
      }}
    />
  );
}
import React, { useState } from "react";
import { EditorState, ContentState, convertToRaw } from "draft-js";
import { Editor } from "react-draft-wysiwyg";
import draftToHtml from "draftjs-to-html";
import htmlToDraft from "html-to-draftjs"
import "./editor.css"

import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";

export const WYSIWYGEditor = (props) => {
  const maxLength = 10000;
  const blocksFromHtml = htmlToDraft(props.value);
  const { contentBlocks, entityMap } = blocksFromHtml;

  const [editorState, setEditorState] = useState(EditorState.createWithContent(
    ContentState.createFromBlockArray(contentBlocks, entityMap)));

  const onEditorStateChange = editorState => {
    setEditorState(editorState);
    return props.onChange(
      draftToHtml(convertToRaw(editorState.getCurrentContent()))
    );
  };

  return (
    <React.Fragment>
      <div className="editor">
        <Editor
          editorState={editorState}
          editorClassName="editorClassName"
          onEditorStateChange={onEditorStateChange}
          toolbar={{
            options: ['inline', 'list'],
            inline: {
              options: ['bold', 'italic', 'underline', 'superscript', 'subscript'],
            },
            list: {
              options: ['unordered', 'ordered'],
            },
          }}
          handleBeforeInput={val => {
            const textLength = editorState.getCurrentContent().getPlainText().length;
            if (val && textLength >= maxLength) {
              return 'handled';
            }
            return 'not-handled';
          }}
          handlePastedText={val => {
            const textLength = editorState.getCurrentContent().getPlainText().length;
            return ((val.length + textLength) >= maxLength);
          }}
        />
      </div>
    </React.Fragment>
  );
};
4

0 回答 0