When typing in ContentEditable, every new character causes the element to blur and presumably re-render. When removing ContentEditable's parent element, Highlight, it stays focused, but unfortunately I need the syntax highlighting functionality. I tried adding a key to ContentEditable as suggested in a similar question, but that didn't work. Any ideas on how to resolve this would be a great help. Thank you!
Main component
var Stdin = React.createClass({
getInitialState: function(){
return {html: ""};
},
handleChange: function(evt){
console.log('evt: ', $.extend({}, evt));
this.setState({html: evt.nativeEvent.target.textContent});
evt.preventDefault();
return false;
},
copyContent: function() {
$("#fake-input").val($("#real-input").html());
return true;
},
render: function () {
return (
<div id="stdin">
<div className="arrow-right"></div>
<form action="#" onSubmit={this.copyContent}>
<input type="text" id="real-input"></input>
<Highlight className='css'>
<ContentEditable key="fake-input" id="fake-input" html={this.state.html} onChange={this.handleChange}/>
</Highlight>
<input type="submit"/>
</form>
</div>
);
}
});
Highlight component
var Highlight = React.createClass({
displayName: 'Highlight',
getDefaultProps: function getDefaultProps() {
return {
innerHTML: false,
className: ''
};
},
componentDidMount: function componentDidMount() {
this.highlightCode();
},
componentDidUpdate: function componentDidUpdate() {
this.highlightCode();
},
highlightCode: function highlightCode() {
var domNode = this.getDOMNode();
var nodes = domNode.querySelectorAll('pre code');
if (nodes.length > 0) {
for (var i = 0; i < nodes.length; i = i + 1) {
hljs.highlightBlock(nodes[i]);
}
}
return false;
},
render: function render() {
if (this.props.innerHTML) {
console.log("hey1");
return React.createElement('div', { dangerouslySetInnerHTML: { __html: this.props.children }, className: this.props.className || null });
} else {
console.log(this.props.children);
return React.createElement(
'pre',
null,
React.createElement(
'code',
{ className: this.props.className, key: 'code-key' },
this.props.children
)
);
}
}
});
ContentEditable component
var ContentEditable = React.createClass({
render: function(){
return React.createElement('div', { onInput: this.emitChange, onBlur: this.emitChange, contentEditable: true, dangerouslySetInnerHTML: {__html: this.props.html}, id: this.props.id, className: this.props.className});
},
shouldComponentUpdate: function(nextProps){
return nextProps.html !== this.getDOMNode().innerHTML;
},
componentDidUpdate: function() {
if ( this.props.html !== this.getDOMNode().innerHTML ) {
this.getDOMNode().innerHTML = this.props.html;
}
},
emitChange: function(evt){
var html = this.getDOMNode().innerHTML;
if (this.props.onChange && html !== this.lastHtml) {
evt.target = { value: html };
this.props.onChange(evt);
}
this.lastHtml = html;
}
});
I've got the same problem. My first solution was to remove all the React.createX()
from the render method. Creating elements in React causes a rerender.
I've still got the problem, but maybe this solves yours.
Try this. The pattern comes from the example for form inputs in react docs.
var ContentEditable = React.createClass({
getInitialState: function(){
return {html: ""};
},
render: function(){
var html = {__html: this.state.html};
return React.createElement('div', { onInput: this.emitChange, onBlur: this.emitChange, contentEditable: true, dangerouslySetInnerHTML: {html}, id: this.props.id, className: this.props.className});
},
componentDidMount() {
if (this.props.html) this.setState({html: this.props.html});
}
componentWillReceiveProps(nextProps) {
if (nextProps.html && (this.state.html != nextProps.html))
{this.setState({html: nextProps.html});}
}
emitChange: function(evt){
var html = this.getDOMNode().innerHTML;
if (this.props.onChange && html !== this.state.html) {
this.setState({html: html})
evt.target = { value: html };
this.props.onChange(evt);
}
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.