Next.js: Error with Draft.js

Created on 14 Apr 2017  路  6Comments  路  Source: vercel/next.js

Hi,

I'm having an error that makes Draft.js not working correctly with Next.js.

Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
 (client) "true" data-editor="7qif3" data-offset-k
 (server) "true" data-editor="rgtv" data-offset-ke

The code is

import React from 'react'
import {Editor, CompositeDecorator, EditorState} from 'draft-js';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group' // ES6




export default class extends React.Component {

  // static async getInitialProps () {
  //   const res = await axios.get('http://api.football-data.org/v1/competitions/426/leagueTable');
  //   return {data: res.data}
  // }


  constructor(props) {
    super(props)

    const compositeDecorator = new CompositeDecorator([
      {
        strategy: handleStrategy,
        component: HandleSpan,
      }
      ]);

    this.state = {editorState: EditorState.createEmpty(compositeDecorator)};

    this.onChange = (editorState) => this.setState({editorState});

  }


  render () {
    return (
      <div>
      <div>

          <style jsx>{`
.example-enter {
  opacity: 0.01;
}

.example-enter.example-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

.example-appear {
  /*opacity: 0.01;*/
  transform: scale(1.2);

}

.example-appear.example-appear-active {
  /*opacity: 1;*/
  transform: scale(1);
  position: absolute;
  transition: all .2s ease-in;

}



    `}</style>

      </div>

        <Editor editorState={this.state.editorState} onChange={this.onChange} />


      </div>
    );
  }
}

      const HANDLE_REGEX = /[\w]+\?\?/g;
      const HASHTAG_REGEX = /\#[\w\u0590-\u05ff]+/g;

      function handleStrategy(contentBlock, callback, contentState) {
        findWithRegex(HANDLE_REGEX, contentBlock, callback);
      }

      function findWithRegex(regex, contentBlock, callback) {
        const text = contentBlock.getText();
        let matchArr, start;
        while ((matchArr = regex.exec(text)) !== null) {
          start = matchArr.index;
          callback(start, start + matchArr[0].length);
        }
      }


        const HandleSpan = (props) => {
        return (

        <ReactCSSTransitionGroup
          transitionName="example"
          transitionEnterTimeout={500}
          data-offset-key={props.offsetKey}
            style={styles.hashtag}
                transitionAppear={true}
      transitionAppearTimeout={500}

          transitionLeaveTimeout={300}>

            {props.children}
        </ReactCSSTransitionGroup>


        );
      };


      const styles = {
        root: {
          fontFamily: '\'Helvetica\', sans-serif',
          padding: 20,
          width: 600,
        },
        editor: {
          border: '1px solid #ddd',
          cursor: 'text',
          fontSize: 16,
          minHeight: 40,
          padding: 10,
        },
        button: {
          marginTop: 10,
          textAlign: 'center',
        },
        handle: {
          color: 'rgba(98, 177, 254, 1.0)',
          direction: 'ltr',
          unicodeBidi: 'bidi-override',
        },
        hashtag: {
          color: 'rgba(95, 184, 138, 1.0)',
          transform:'translate(30px, 2px)',
          transition:'1s all'
        },
      };


Thanks

Most helpful comment

@arefaslani, try with this example:
https://github.com/facebook/draft-js/tree/master/examples/draft-0-10-0/universal

Basically create the Editor with createWithContent(emptyContentState).

I tried this quickly and didn't get the error.

impronunciable's solution (scroll up) also works to only render the Editor component after componentDidMount by setting a flag.

All 6 comments

Try adding an editorKey="editor" prop. I use draft in a project with next and don't receive any errors.

The solution @knipferrc presents will work on the next draft-js release since the editorKey pr got merged in march while the last version is from january https://github.com/facebook/draft-js/pull/796

An easy solution until that happens is to add a editor boolean variable to your state starting as false and turning it to true on componentDidMount. Then on render you only render the <Editor> if this.state.editor is true

Thanks all for helping.
@ellyish please re-open if you still didn't find a workaround.

This is my component:

import React, { Component } from 'react'
import { Editor, EditorState } from "draft-js";

export default class CHEditor extends Component {
  state = { editorState: EditorState.createEmpty() }

  onChange = editorState => this.setState(editorState)

  render() {
    return (
      <Editor
        editorKey="editor"
        onChange={editorState => this.onChange(editorState)}
        editorState={this.state.editorState}
        placeholder="Simple editor"
      />
    )
  }
}

and I'm still getting same error:

Warning: Propdata-offset-keydid not match. Server: "c2j7b-0-0" Client: "60n2f-0-0"

@arefaslani, try with this example:
https://github.com/facebook/draft-js/tree/master/examples/draft-0-10-0/universal

Basically create the Editor with createWithContent(emptyContentState).

I tried this quickly and didn't get the error.

impronunciable's solution (scroll up) also works to only render the Editor component after componentDidMount by setting a flag.

@rolfnl in your example you explicitely pass a key to your empty block. This doesn't solve the problem of rendering arbitrary content serverside (and I think it doesn't matter if you provide an editorKey prop when you hardcode the block's key)

However this seems not to be a solution to render content on the server without getting a mismatch (and an error because the client tries to load the wrong keypath from the tree via getUpdatedSelectionState())

Or am I missing something?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sospedra picture sospedra  路  3Comments

jesselee34 picture jesselee34  路  3Comments

kenji4569 picture kenji4569  路  3Comments

DvirSh picture DvirSh  路  3Comments

YarivGilad picture YarivGilad  路  3Comments