Draft.js (react-draft-wysiwyg):从编辑器组件外部进行文本更新不起作用

2024-04-15

我正在尝试将文本从调用组件更新到编辑器组件中。我用props从调用者传递文本,但是当文本更改(内容编辑器中更新属性)时,编辑器组件中的文本不是:

下面是调用组件的代码:

<ControlledEditor htmlContent={this.state.validationResultContent}/>

这是受控编辑器的代码:

    export class ControlledEditor extends Component {
    constructor(props) {
        super(props);
        this.state = {editorState: EditorState.createWithText(this.props.htmlContent)};
    }


    onEditorStateChange = (editorState) => {
        this.setState({ editorState })
    };

    render() {

        const { editorState } = this.state;

        return (
            <>
                <Container className="mt-5">
                    <Row>
                        <Editor
                            editorState= {editorState}
                            onEditorStateChange={this.onEditorStateChange}
                            wrapperClassName="demo-wrapper"
                            editorClassName="demo-editor"

                        />
                    </Row>
                </Container>
            </>
        );
    }
}

ControlledEditor.propTypes = {
    htmlContent: PropTypes.string
}

谢谢您的帮助

------- 更新 1 -------

  • 我在用着反应草案所见即所得构建到 Draft.js 上
  • 要呈现的文本是 HTML,所以我更新了代码
  • 回答来自琳达·派斯特 with 组件更新解决了主要问题link https://stackoverflow.com/a/69239847/121804

遵循工作代码(对我来说):

export class ControlledEditor extends Component {
    constructor(props) {
        super(props);
        this.state = {editorState: EditorState.createEmpty()}
    }

    componentDidUpdate(prevProps) {
        if (this.props.htmlContent !== prevProps.htmlContent) {
            this.setState({
                    editorState: EditorState.createWithContent(ContentState.createFromBlockArray(convertFromHTML(this.props.htmlContent)))
            });
        }
    }

    onEditorStateChange = (editorState) => {
        this.setState({editorState})
    };

    render() {
        const {editorState} = this.state;
        return (
            <>
                <Container className="mt-5">
                    <Row>
                        <Editor
                            editorState={editorState}
                            wrapperClassName="demo-wrapper"
                            editorClassName="demo-editor"
                            onEditorStateChange={this.onEditorStateChange}
                        />
                    </Row>
                </Container>
                <Container className="mt-5">
                    <Row>
                        <div dangerouslySetInnerHTML={{__html: this.props.htmlContent}}/>
                    </Row>
                </Container>
              
            </>
        );
    }
}

ControlledEditor.propTypes = {
    htmlContent: PropTypes.string
}

可选:更新 Draft.js 版本

您正在使用的某些属性似乎没有记录。也许它们来自以前的版本draft-js?但我会根据当前文档来写这个答案。

The onEditorStateChange的支柱Editor应该重命名为onChange https://draftjs.org/docs/api-reference-editor#onchange.

没有createFromText on EditorState。此替换涉及两个步骤:

  1. ContentState可以使用静态方法从文本创建ContentState.createFromText https://draftjs.org/docs/api-reference-content-state#createfromtext.
  2. EditorState可以从创建ContentState使用静态方法EditorState.createWithContent https://draftjs.org/docs/api-reference-editor-state#createwithcontent

所以初始状态应该是:

this.state = {
  editorState: EditorState.createWithContent(
    ContentState.createFromText(this.props.htmlContent)
  )
};

核心问题

这样,我就可以运行您的代码并重现您的问题:

我使用 props 传递来自调用者的文本,但是当文本更改(props 在 ContentEditor 中更新)时,编辑器组件中的文本不会更新。

你正在创造this.state.editorState基于的价值this.props.htmlContent 在构造函数中。该部分代码仅在以下情况下运行一次:ControlledEditor首先安装组件。当 props 改变时它会重新运行,所以它无法响应this.props.

你需要添加一个componentDidUpdate https://reactjs.org/docs/react-component.html#componentdidupdate生命周期方法。

componentDidUpdate(prevProps) {
  if (this.props.htmlContent !== prevProps.htmlContent) {
    this.setState({
      editorState: EditorState.createWithContent(
        ContentState.createFromText(this.props.htmlContent)
      )
    });
  }
}

在我看来,将其转换为函数组件并使用钩子更容易。

import { useEffect, useState } from "react";
import { Editor, EditorState, ContentState } from "draft-js";
import "draft-js/dist/Draft.css";

// helper function
const createState = (text) => {
  return EditorState.createWithContent(ContentState.createFromText(text));
};

const ControlledEditor = ({ htmlContent }) => {
  // define the local state, using the createState callback to create the initial value
  const [editorState, setEditorState] = useState(createState(htmlContent));

  // override the local state any time that the props change
  useEffect(() => {
    setEditorState(createState(htmlContent));
  }, [htmlContent]);

  return (
    <Editor
      editorState={editorState}
      onChange={setEditorState}
    />
  );
};

export default function App() {
  const [text, setText] = useState("Hello World");
  return (
    <div>
      <h2>Source Text</h2>
      <textarea value={text} onChange={(e) => setText(e.target.value)} />
      <h2>Editor</h2>
      <ControlledEditor htmlContent={text} />
    </div>
  );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Draft.js (react-draft-wysiwyg):从编辑器组件外部进行文本更新不起作用 的相关文章

随机推荐

  • 如何将光标设置在edittext的末尾

    每当我触摸编辑文本时 光标应该位于末尾 即使编辑文本已经有一些文本并且它不应该允许向左移动奖项 editTextView setOnTouchListener new View OnTouchListener Override public
  • 查找当前 Vim 折叠的第一行

    我正在编写一个 Vimscript 函数 其中我需要查找当前折叠的第一行的行号 到目前为止我一直在使用这个 function GetFoldStart let l current line line normal z let l curre
  • 使用 Python 在 Google 中搜索

    我想使用 python 脚本在 Google 中搜索文本 并返回每个结果的名称 描述和 URL 我目前正在使用这段代码 from google import search ip raw input What would you like t
  • OSX Mountain Lion 上新安装的 RVM Ruby 1.9.3 出现“bad ecpoint”SSL 错误

    尝试使用 Ruby 1 9 3 rest client发出 https 请求 例如 RestClient get https google com 总是给我一个 SSL 错误 OpenSSL SSL SSLError SSL connect
  • 在VB6中使用Sax解析编辑和编写XML

    因此 我尝试使用 VB6 中的 SAX 解析 对于古老的 COM 组件 来编辑 xml 输出是 xml 我更喜欢使用 DOM 解析 但 xml 的大小 可能超过 20MB 迫使我使用 SAX 我对 VB6 比较陌生 并且没有 SAX 解析经
  • 在这种情况下,数组索引中的字符表示如何工作?

    我是 C 初学者 我有这样的代码 include
  • 使用适用于 Android 的新 Facebook SDK 将内容添加到 Facebook feed 对话框

    我知道this https stackoverflow com questions 4450517 adding content to facebook feed dialog from facebook sdk for android线程
  • EntityFramework 是否可用于 Windows 8 应用商店应用程序?

    EntityFramework 是否可用于 Windows 8 应用商店应用程序 我正在使用适用于 Windows 8 的 Visual Studio 2012 Express 我开始怀疑 因为我无法让它发挥作用 我从 NuGet 安装了实
  • Delphi:使组件对实时绑定可见

    我一直在尝试制作一个具有对视觉绑定表单可见的字符串属性的测试对象 该组件已使用适当的属性进行注册 使用 XE8 和 Firemonkey 我可以通过使用隐藏显示元素选择它来使其显示在可视绑定器上 但是我无法让它将 Foo 字符串绑定到 TE
  • 如何更改 Kendo 警报标题?

    我正在使用 Kendo 警报并想更改其标题 默认标题是 url 名称 请参阅下面的链接 图片 我想使用自己的标题 如何更改 图像剑道警报 https i stack imgur com AscDa png 剑道警报 kendo alert
  • Graphviz 允许边缘节点重叠

    我想在项目中使用 graphviz 但无法获得我想要的行为 我有一个可以用 graphviz 绘制的图表 但我也有同一个图表的一个版本 它有一些额外的边 我希望绘制第二个图时 节 点与第一个图的位置相同 边缘也位于相同的位置 但绘制新的边缘
  • Silverlight 3:没有变化,但现在我收到“找不到页面”

    有一个工作正常的页面 我所做的唯一更改是向页面添加一个数据网格 其中还添加了 xmlns 突然间我得到了 找不到页面 检查了 UriMappings 尝试了默认导航链接 没有喜悦 Ideas 更新 答案是我有一个没有初始化集合的模拟类 请参
  • 何时使用filter_input()

    这个问题最初是在评论中提出的here https stackoverflow com questions 768442 php filter input comment 580014 Is 过滤器输入 http www php net ma
  • 在 VSCode 中每次保存时运行 rsync

    我的本地系统上有一个存储库 并正在远程服务器上测试我的更改 我正在使用 VSCode 进行开发 我希望每次保存时 rsync 都应在后台运行 并将当前本地文件中的更改与远程同步 我如何使用 VSCode 实现这一目标 我在用保存并运行 ht
  • 什么时候适合响应 HTTP 412 错误?

    我不清楚什么时候应该或不应该返回 HTTP 412 先决条件失败 Web 服务错误 我正在考虑在验证数据时使用它 例如 如果客户端 POST 的 XML 数据并且该数据缺少必需的数据元素 则以 412 和错误描述进行响应 这是否符合 HTT
  • UIImage 到 base64 字符串编码

    如何转换UIimage到base64编码的字符串 我找不到任何详细的示例或代码 我想知道你为什么没有找到你的问题 因为这是一个非常古老的问题并且可以找到here https stackoverflow com questions 39246
  • 具有自定义 PropertyDescriptor 的 PropertyGrid

    我一直在努力让自定义属性描述符按照我想要的方式使用 PropertyGrid 工作 前提 我有一个名为 Animal 的类 其中包含以下属性Age Type Location and Name 我有另一个名为 AnimalGroup 的类
  • 如何查询C++的GCC警告?

    GCC 允许使用以下语法查询特定于 C 语言的可用警告标志 g Q help warning c 向调用中添加警告标志会将它们包含在结果中 g Wall Q help warning c 然而 似乎调用是从 C 的角度完成的 我不知道如何从
  • 我无法导入textblob包

    我使用命令安装了textblobpip install 但现在我尝试导入它 但出现以下错误 ModuleNotFoundError 没有名为 textblob 的模块 我在Windows 10系统中使用Spyder from textblo
  • Draft.js (react-draft-wysiwyg):从编辑器组件外部进行文本更新不起作用

    我正在尝试将文本从调用组件更新到编辑器组件中 我用props从调用者传递文本 但是当文本更改 内容编辑器中更新属性 时 编辑器组件中的文本不是 下面是调用组件的代码