Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with Draft.js #1722

Closed
ellyish opened this issue Apr 14, 2017 · 6 comments
Closed

Error with Draft.js #1722

ellyish opened this issue Apr 14, 2017 · 6 comments

Comments

@ellyish
Copy link

ellyish commented Apr 14, 2017

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

@mistakenelf
Copy link

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

@impronunciable
Copy link
Contributor

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 facebookarchive/draft-js#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

@arunoda
Copy link
Contributor

arunoda commented May 2, 2017

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

@arefaslani
Copy link

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: Prop data-offset-key did not match. Server: "c2j7b-0-0" Client: "60n2f-0-0"

@rolfnl
Copy link

rolfnl commented Dec 31, 2017

@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.

@erikmueller
Copy link

@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?

@lock lock bot locked as resolved and limited conversation to collaborators Jul 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants