I have used emojione and this code snippet to basically come up with a very non-react solution as shown below. Hope it helps.
import React from 'react';
import {render} from 'react-dom';
import emojione from 'emojione';
class App extends React.Component {
constructor(props) {
super(props);
}
updateText = () => {
const html = emojione.shortnameToImage(this.refs.inputDiv.innerHTML);
let sel, range;
if (window.getSelection) {
// IE9 and non-IE
sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
// Range.createContextualFragment() would be useful here but is
// non-standard and not supported in all browsers (IE9, for one)
let el = this.refs.inputDiv;
el.innerHTML = html;
let frag = document.createDocumentFragment(), node, lastNode;
while ((node = el.firstChild)) {
lastNode = frag.appendChild(node);
}
range.insertNode(frag);
// Preserve the selection
if (lastNode) {
range = range.cloneRange();
range.setStartAfter(lastNode);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
} else if (document.selection && document.selection.type !== "Control") {
// IE < 9
document.selection.createRange().pasteHTML(html);
}
};
render() {
return (
<div ref="inputDiv" contentEditable onInput={this.updateText}/>
);
}
}
render(<App/>, document.getElementById('root'));
Here is the working example
https://codesandbox.io/s/ol2lmkqqlq