Draft-js: A component is `contentEditable` and contains `children` managed by React warning

Created on 25 Feb 2016  ยท  12Comments  ยท  Source: facebook/draft-js

When integrating draft-js into an existing project I get

Warning: A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not intentional.

I am using the rich text example, and that gives me this warnings:

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of BlockStyleControls. See https://fb.me/react-warning-keys for more information.

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of InlineStyleControls.

using the rich.htmlexample from the repository

Most helpful comment

Yes, Just use suppressContentEditableWarning in your component.
Be aware that this is not related with draftjs but with the use of any div that is content editable, so you may ne having this warning at another component.
That was my case...

Let me know, glad to help.

BTW I dont know how to make a mention on mobile phone... :( do you?

All 12 comments

Known problem. http://facebook.github.io/draft-js/docs/advanced-topics-issues-and-pitfalls.html#react-contenteditable-warning

React 15 will give a way to silence this.

The key warnings could be fixed though.

Hello, I am still having this warning, but I checked the draft-js code (0.7.0 version) and it has the suppressContentEditableWarning: true, prop in the file.

I also have react 15.3.1 so, I am wondering what could be wrong.

screenshot from 2016-08-23 09-10-31

@jmaguirrei You must not actually have react-dom 15.3.1. Check npm ls for the full dependency tree.

@spicyj Thanks. I wasn't with react-dom 15.3.1, but after upgrade I am still having same warning.

If I go to the function the console shows in ReactDOMComponent.js this is:

function assertValidProps(component, props) {
  if (!props) {
    return;
  }
  // Note the use of `==` which checks for null or undefined.
  if (voidElementTags[component._tag]) {
    !(props.children == null && props.dangerouslySetInnerHTML == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, '%s is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`.%s', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : _prodInvariant('137', component._tag, component._currentElement._owner ? ' Check the render method of ' + component._currentElement._owner.getName() + '.' : '') : void 0;
  }
  if (props.dangerouslySetInnerHTML != null) {
    !(props.children == null) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.') : _prodInvariant('60') : void 0;
    !(typeof props.dangerouslySetInnerHTML === 'object' && HTML in props.dangerouslySetInnerHTML) ? process.env.NODE_ENV !== 'production' ? invariant(false, '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.') : _prodInvariant('61') : void 0;
  }
  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(props.innerHTML == null, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.') : void 0;
    process.env.NODE_ENV !== 'production' ? warning(props.suppressContentEditableWarning || !props.contentEditable || props.children == null, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0;
    process.env.NODE_ENV !== 'production' ? warning(props.onFocusIn == null && props.onFocusOut == null, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.') : void 0;
  }
  !(props.style == null || typeof props.style === 'object') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + \'em\'}} when using JSX.%s', getDeclarationErrorAddendum(component)) : _prodInvariant('62', getDeclarationErrorAddendum(component)) : void 0;
}

// and below in the file...

var RESERVED_PROPS = {
  children: null,
  dangerouslySetInnerHTML: null,
  suppressContentEditableWarning: null
};

// and in npm ls
โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”‚ โ””โ”€โ”€ [email protected]
โ”‚ โ””โ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”€ [email protected]
โ”œโ”€โ”ฌ [email protected]
โ”‚ โ”œโ”€โ”€ [email protected]
โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚   โ””โ”€โ”€ [email protected]

Any idea why this is happening?

No, I'm not sure.

@jmaguirrei did you succeed? I'm having the same issue

Yes, Just use suppressContentEditableWarning in your component.
Be aware that this is not related with draftjs but with the use of any div that is content editable, so you may ne having this warning at another component.
That was my case...

Let me know, glad to help.

BTW I dont know how to make a mention on mobile phone... :( do you?

@martriay Try putting the property at the containing div of the editor, like:

  render() {

    const
      { isSelectionActive, selectionCoords } = this,
      { size, owner } = this.props,
      readOnly = !owner;

    return (
      <div
        style={styles({})['my-editor']}
        onClick={this.onFocus}
        onBlur={this.onSave}
        suppressContentEditableWarning={true}
      >
        <div id={this.props.id} className='editor-scroll' style={styles({ size })['editor']}>
          <Editor
            editorState={this.state.editorState}
            onChange={this.onChange}
            handleKeyCommand={this.handleKeyCommand}
            keyBindingFn={this.myKeyBindingFn}
            handleBeforeInput={this.handleBeforeInput}
            readOnly={readOnly}
            placeholder={this.placeholder}
            ref='editor'
          />
        </div>
        {
          isSelectionActive &&
          <div style={styles({ selectionCoords })['selection']}>
            MySelection
          </div>
        }
      </div>
    );
  }

@jmaguirrei thank you very much! But I ended suppressing it manually:

console.error = (function(_error) {
  return function(message) {
    if (typeof message !== 'string' || message.indexOf('component is `contentEditable`') === -1) {
      _error.apply(console, arguments)
    }
  }
})(console.error)

@martriay Nice solution to have as a general escape... Thanks also!

@jmaguirrei suppressContentEditableWarning is work fine, Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

roundrobin picture roundrobin  ยท  3Comments

ianstormtaylor picture ianstormtaylor  ยท  3Comments

snaerth picture snaerth  ยท  3Comments

mvnnn picture mvnnn  ยท  3Comments

pklavins picture pklavins  ยท  3Comments