So my draft-js editor becomes really slow(hacky) the more content I insert (after about 20 decorator replacements). I am guessing this behavior is due to the decorator which checks the entire editor content using regex and replaces the matches with emoji component every time the state changes. I am also creating entities for each of the matches the regex find, I do this by decorating the component with editor state as a prop. Is there a way to make it faster? Here is my decorator :
{
strategy: emojiStrategy,
component: decorateComponentWithProps(RenderEmoji, {
getEditorState: this.getEditorState,
setEditorState: this.onChange
})
}
here is my emojiStrategy :
function emojiRegexF(regex, contentBlock, callback, contentState) {
const text = contentBlock.getText();
let matchArr, start;
while ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
callback(start, start + matchArr[0].length);
}
}
function emojiStrategy(contentBlock, callback, contentState) {
emojiRegexF(EMOJI_REGEX, contentBlock, callback, contentState);
}
here is my RenderEmoji component:
const RenderEmoji = props => {
const contentBlock = props.children[0].props.block;
const emojiKey = contentBlock.getEntityAt(props.children[0].props.start);
const emojiShortName = props.decoratedText;
if (!emojiKey) {
setEntity(props, emojiShortName);
}
return (
<Emoji emoji={emojiShortName} set="emojione" size={24}>
{props.children}
</Emoji>
);
};
and here is my setEntity function that sets the entity for the match:
function setEntity(props, emojiShortName) {
const editorState = props.getEditorState();
const contentstate = editorState.getCurrentContent();
const contentStateWithEntity = contentstate.createEntity(
"emoji",
"IMMUTABLE",
{
emojiUnicode: emojiShortName
}
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const oldSelectionState = editorState.getSelection();
const selectionState = oldSelectionState.merge({
focusOffset: props.children[0].props.start + props.decoratedText.length,
anchorOffset: props.children[0].props.start
});
const newContentState = Modifier.applyEntity(
contentstate,
selectionState,
entityKey
);
const withBlank = Modifier.replaceText(
newContentState,
selectionState,
emojiShortName + " ",
null,
entityKey
);
const newEditorState = EditorState.push(
editorState,
withBlank,
"apply-entity"
);
props.setEditorState(newEditorState);
}
Any way I can optimize this? Thanks