问题描述
我正在尝试实现一个功能,让我可以在 Draft.js 编辑器中拖动装饰文本,并在这个问题上花费了几天的脑力。
蓝色高光是歌词中的和弦,我的目标是调整它们在文本中的位置。
我的策略
我知道我正在创建一个 race condition in Draft.js,但我不知道如何解决这个问题。
代码
我在 Github 上有一个测试设置。
https://github.com/tobi-or-not/draft-js-experiments
场景 1:
我在显示编辑器的同一组件中单击了一个按钮。这完美地工作。按下按钮后,部分文字被标记
场景 2:
我点击装饰器。点击后,编辑器回到初始状态
一定有我不明白的地方。也许有更好的方法来实现这种拖放。非常感谢您的想法和提示!
解决方法
我偶然发现对 Draft.js Slack 的评论为我指明了正确的方向。
您只将装饰器传递到初始状态,但是:
- 装饰器关闭了 Button 组件(在第一个呈现的实例中,而不是当前实例中)
- Button 组件关闭了 clickFn(在同一个 FIRST 渲染实例中)
- clickFn 关闭了 editorState(猜猜是什么......在同一个第一个渲染实例中)
因此您的 clickFn 总是更新原始状态,而不是当前状态
操蛋,不是吗?您基本上必须在每次更新时更新装饰器,以将事物正确链接到以前的状态。这都是因为 DraftJS EditorState 不仅仅是数据对象,还包括通过装饰器产生的副作用。
最简单的方法可能是使用好的旧类组件,以便闭包始终指向同一个对象,而不是每次都指向一个新对象。
这就是我所做的。包含 Draft.js 编辑器的组件现在是一个类组件。 The code is available on GitHub。