我正在使用 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>
);
};