react-codemirror: Code mirror value doesn't update with state change in v1.0.0

Changing props.value does not re-render code mirror. This is a new issue in v1.0.0, previously this worked. Changing props.value via the onChange event works fine, but programmatically changing props.value does not call a re-render.

This can be reproduced with the following code.

class Editor extends Component {
    constructor() {
        super();
        this.state = { value: 'abc' };
    }

    render() {
        const { value } = this.state;
        console.log(value);
        return (
            <div>
                <CodeMirror value={value} />
                <button onClick={() => this.setState({ value: 'def' })}>Click to change value</button>
            </div>
        );
    }
}

This appears like it may have something to do with this change listed in the history file: fixed; Only updates the CodeMirror value if props.value has changed.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 59
  • Comments: 27 (3 by maintainers)

Commits related to this issue

Most upvoted comments

PS. Try using referencing my branch in your package.json (temporarily!) to see it solves your issues as well:

"react-codemirror": "git://github.com/skidding/react-codemirror.git#106-fix-update",

Update: You might want to use https://github.com/scniro/react-codemirror2

+1 whats going on with this? Merging the PR fix would be soooooper

Also, should anyone find this useful I threw up a super quick package on npm => react-codemirror2. If others find this useful I’ll be happy to maintain it moving forward and build it up however we see fit.

@MrSauceman Of course. It’s pretty bare bones, but here is what does the trick for me with some sample options…

wrapper

import React from 'react';
let codemirror = require('codemirror');

export default class CodeMirror extends React.Component {

  componentDidMount() {

    this.editor = codemirror(this.ref);
    this.editor.on('change', () => this.props.onChange(this.editor.getValue()));
  }

  componentWillReceiveProps(nextProps) {

    Object.keys(nextProps.options || {}).forEach(key => this.editor.setOption(key, nextProps.options[key]));
    this.editor.setValue(nextProps.value || '');
  }

  render() {
    return (
      <div ref={(self) => this.ref = self}/>
    )
  }
}

usage

<CodeMirror 
  value='foo' 
  options={{theme: 'material', viewportMargin: Infinity}} 
  onChange={value => {console.log(value); }} />

where value and options can be passed as a living prop from the parent component

Another work around: add a key prop to the codemirror component. Then key = key + 1 when the value prop changes. This makes the editor re-mount. It’s ok for me because the value prop only changes when the user clicks the ‘reset’ button.

FWIW I tried it on a fresh project and couldn’t get that feature to work. I switched to Ace editor which does the trick for me.

I’m not putting that comment to be dismissive or aggressive but as someone who doesn’t know these libraries very well it took me a while to find out so here’s a link: https://github.com/securingsincity/react-ace

I’m having this issue as well, gradly I’ve found this post! I’ll try the solutions here mentioned but it would be really awesome to get this merged soon!

Edit: Please try https://github.com/scniro/react-codemirror2 instead. That fork is maintained, available via npm and gathering stars.

~I can confirm that @skidding/react-codemirror works. Newbies guide:~

  • ~In your app code replace import CodeMirror from 'react-codemirror'; with import CodeMirror from '@skidding/react-codemirror';~
  • ~delete package-lock.json (there are probably better ways)~
  • ~in package.json replace "react-codemirror": "^1.0.0", with "@skidding/react-codemirror": "^1.0.0",~
  • ~run npm install, run webpack/wait for compile/reload bowser~
  • ~redux store values are correctly swapping (for us on locale switching)~

Bump! I’m having this issue too!

@skidding you version of codemirror worked perfectly! yay. we were having so many issues with this. We were able to roll back to 0.2.6, and it worked, but then when we moved our state into a redux store, and codemirror stopped updating 😦.

Fortunately when using import CodeMirror from '@skidding/react-codemirror'; Everything worked perfectly!! For those curious…

In the end it was simple as this:

      <CodeMirror 
        value={this.props.code}
        onChange={this.codeChange}
        options={options} />
    );

, but it only worked using that library I referenced earlier. Hopefully that pull request will fix the issue, please update here when it has been merged.

For anyone who’s still hung up on this or considering another editor, I’d highly recommend giving the raw codemirror library a look to use directly. I’m doing so with a tiny component wrapper I rolled and it’s very straightforward. One less dep too (lodash as well)…

Edit: Please try https://github.com/scniro/react-codemirror2 instead. That fork is maintained, available via npm and gathering stars.

Published my fork under @skidding/react-codemirror until #107 gets merged or resolved otherwise.

Update: You might want to use https://github.com/scniro/react-codemirror2

@MartinHaeusler We ran into that issue too with the v1 update, introduced by this commit https://github.com/JedWatson/react-codemirror/commit/339b5975724cde338301f4c6842f2d52b4773e76. Your best bet is to either…

  1. use ^0.3.0 and suffer the deprecation warnings
  2. roll your own codemirror wrapper (that’s what we ended up doing)

Bummer that we had abandon this project but supporting your own wrapper is actually not too difficult.