Select text in Draft.js decorator onClick 装饰器实现拖拽
Select text in Draft.js decorator onClick on decorator to implement drag and drop
我正在尝试实现一项功能,让我可以在 Draft.js 编辑器中拖动装饰文本,并且在这个问题上花费了几天的脑力。
蓝色高光是歌词中的和弦,我的目标是调整它们在文本中的位置。
我的攻略
- 点击装饰器时在装饰器内标记文本
onClick
- 移动标记的文本
我知道我正在创建一个 race condition in Draft.js 但我不知道如何解决这个问题。
代码
我有一个测试设置,可在 Github 上使用。
https://github.com/tobi-or-not/draft-js-experiments
场景 1:
我在显示编辑器的同一组件中单击了一个按钮。这非常有效。按下按钮后,部分文字被标记
场景 2:
我点击装饰器。点击后,编辑器回到初始状态
一定有什么不明白的地方。也许有更好的方法来实现这种拖放操作。非常感谢您的想法和提示!
我在 Draft.js Slack 上偶然发现了一条评论,它为我指明了正确的方向。
You only pass the decorator to initial state, but:
- The decorator has closure to the Button component (in the FIRST rendered instance, not current instance)
- Button component has closure to clickFn (in the same FIRST rendered instance)
- clickFn has closure to editorState (guess what ... in the same FIRST rendered instance)
Therefore your clickFn always updates the original state, not the current state
Mindfuck, isn't it? You would basically have to update the decorator with each update to keep things linked properly to previous state. This is all caused by the fact that DraftJS EditorState is not just data object, but includes side-effects through the decorator.
The easiest way out of this is probably to use good old class components, so that the closures keep pointing to the same object, not a new one everytime.
我就是这么做的。包含 Draft.js 编辑器的组件现在是 class 组件。 The code is available on GitHub.
我正在尝试实现一项功能,让我可以在 Draft.js 编辑器中拖动装饰文本,并且在这个问题上花费了几天的脑力。
蓝色高光是歌词中的和弦,我的目标是调整它们在文本中的位置。
我的攻略
- 点击装饰器时在装饰器内标记文本
onClick
- 移动标记的文本
我知道我正在创建一个 race condition in Draft.js 但我不知道如何解决这个问题。
代码
我有一个测试设置,可在 Github 上使用。
https://github.com/tobi-or-not/draft-js-experiments
场景 1:
我在显示编辑器的同一组件中单击了一个按钮。这非常有效。按下按钮后,部分文字被标记
场景 2:
我点击装饰器。点击后,编辑器回到初始状态
一定有什么不明白的地方。也许有更好的方法来实现这种拖放操作。非常感谢您的想法和提示!
我在 Draft.js Slack 上偶然发现了一条评论,它为我指明了正确的方向。
You only pass the decorator to initial state, but:
- The decorator has closure to the Button component (in the FIRST rendered instance, not current instance)
- Button component has closure to clickFn (in the same FIRST rendered instance)
- clickFn has closure to editorState (guess what ... in the same FIRST rendered instance)
Therefore your clickFn always updates the original state, not the current state Mindfuck, isn't it? You would basically have to update the decorator with each update to keep things linked properly to previous state. This is all caused by the fact that DraftJS EditorState is not just data object, but includes side-effects through the decorator.
The easiest way out of this is probably to use good old class components, so that the closures keep pointing to the same object, not a new one everytime.
我就是这么做的。包含 Draft.js 编辑器的组件现在是 class 组件。 The code is available on GitHub.