You can do any operations with the editor state without the component updating. So you can add a text that you need, after that programmatically set selection on this text and finally create a link and update your component.
Look at this working example - https://jsfiddle.net/levsha/2op5cyxm/
Here I add a link after a button click.
handleAddLink = () => {
const { editorState } = this.state;
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const currentBlock = contentState.getBlockForKey(selectionState.getStartKey());
const currentBlockKey = currentBlock.getKey();
const blockMap = contentState.getBlockMap();
const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === currentBlock));
const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === currentBlock)).rest();
const newBlockKey = genKey();
// add new ContentBlock to editor state with appropriate text
const newBlock = new ContentBlock({
key: newBlockKey,
type: 'unstyled',
text: linkText,
characterList: new List(Repeat(CharacterMetadata.create(), linkText.length)),
});
const newBlockMap = blocksBefore.concat(
[[currentBlockKey, currentBlock], [newBlockKey, newBlock]],
blocksAfter
).toOrderedMap();
const selection = editorState.getSelection();
const newContent = contentState.merge({
blockMap: newBlockMap,
selectionBefore: selection,
selectionAfter: selection.merge({
anchorKey: newBlockKey,
anchorOffset: 0,
focusKey: newBlockKey,
focusOffset: 0,
isBackward: false,
}),
});
let newEditorState = EditorState.push(editorState, newContent, 'split-block');
// programmatically apply selection on this text
const newSelection = new SelectionState({
anchorKey: newBlockKey,
anchorOffset: 0,
focusKey: newBlockKey,
focusOffset: linkText.length
});
newEditorState = EditorState.forceSelection(newEditorState, newSelection);
// create link entity
const newContentState = newEditorState.getCurrentContent();
const contentStateWithEntity = newContentState.createEntity(
'LINK',
'IMMUTABLE',
{ url: linkUrl }
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
newEditorState = EditorState.set(newEditorState, { currentContent: contentStateWithEntity });
newEditorState = RichUtils.toggleLink(newEditorState, newEditorState.getSelection(), entityKey);
// reset selection
newSelection = new SelectionState({
anchorKey: newBlockKey,
anchorOffset: linkText.length,
focusKey: newBlockKey,
focusOffset: linkText.length
});
newEditorState = EditorState.forceSelection(newEditorState, newSelection);
// update our component
this._handleChange(newEditorState);
}