首页 > 解决方案 > 如何在 Draftjs 中实现自定义装饰器

问题描述

我正在尝试为我的 draft.js 组件实现自定义装饰器。我不想使用 CompositeDecorator,因为我想根据输入渲染可能许多不同类型的装饰。除了 Draft.js 存储库中的类型定义之外,我找不到 DraftDecoratorType 的任何文档 - https://github.com/facebook/draft-js/blob/master/src/model/decorators/DraftDecoratorType.js

我在https://github.com/SamyPesse/draft-js-prism/blob/master/lib/index.js中获得了灵感,我决定尝试使用小步骤 - 只需编写一个装饰器,使单词以 # 粗体开头。

到目前为止我使用的装饰器可以在下面找到。

this.state = {
            editorState: Draft.EditorState.createEmpty({
                getComponentForKey(key: string): Function {
                    const originalText = key.split('.')[0];
                    return () => <b>{originalText}</b>;
                },
                getPropsForKey(key: string): any {
                    return {};
                },

                getDecorations(block: any, contentState: any): any {

                    const text = block.getText();
                    const decorations: Array<string | null> = Array(text.length).fill(null);

                    let counter = 0;
                    let result: RegExpExecArray;

                    const regex = /(^|\s)#\w+/g;
                    while ((result = regex.exec(text) as RegExpExecArray) != null) {
                        const start = result.index;
                        const end = start + result[0].length;
                        decorations.fill(result[0] + '.' + counter, start, end);
                        counter++;
                    }

                    console.log(decorations);
                    return Immutable.List(decorations);
                }
            })
        };

我的组件的完整代码可以在https://github.com/d-kozak/react-playground/blob/master/src/draftjs/CustomDecoratorExample.tsx找到

不幸的是,当我使用它时,编辑器开始出现不可预测的行为。目前,当我输入#后跟一个字符(例如#a)时,即触发装饰器时,文本确实变粗了,但是焦点移到了文本区域的开头,然后它只是表现非常不可预测。很难描述,但您可以在这里亲自尝试:https ://dkozak-react-playground.netlify.com

我在https://github.com/d-kozak/react-playground/blob/master/src/draftjs/CompositeDecoratorExample.tsx使用 CompositeDecorator 实现了基本相同的装饰器,它按预期工作。如果您打开我的 netlify 页面,可以在同一页面的另一个选项卡上找到现场演示。

但是我的自定义装饰器中的某些东西完全使编辑器崩溃,但我不确定为什么以及如何修复它。有人可以帮帮我吗?

标签: reactjsdraftjs

解决方案


我相信解决方法是将您的返回值替换getComponentForKey

(props) => <b>{props.children}</b>;

如果您查看孩子,您会发现它带有各种键,我假设Draft.js使用这些键来确定您是否更改了元素。您的版本不包含这些信息,因此可能重新创建了元素,或者您的光标被重置,因为它不知道在哪里放置这个明显的新元素。


推荐阅读