react-codemirror icon indicating copy to clipboard operation
react-codemirror copied to clipboard

Code mirror value doesn't update with state change in v1.0.0

Open MrSauceman opened this issue 8 years ago • 28 comments

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.

MrSauceman avatar May 15 '17 14:05 MrSauceman

Same issue here, @MrSauceman, do you have a workaround?

marcioaffonso avatar May 15 '17 19:05 marcioaffonso

Created a PR to fix this https://github.com/JedWatson/react-codemirror/pull/107. I've commented on this issue two days ago:

I think this revealed another bug. In my case the Codemirror is no longer updated even when props change. I'm pretty sure it's because componentWillReceiveProps is debounced, which results in this.props being equal to nextProps when the lifecycle method is called in the next loop.

@JedWatson what do you think about no longer debouncing componentWillReceiveProps? We could make it optional, but I wouldn't bother since I believe it is not compatible with the React lifecycle model. If performance is the concern then let's leave the debouncing up to the user.

This is the PR that that introduced the debouncing: https://github.com/JedWatson/react-codemirror/pull/35. Maybe @alexdmiller has more insight into this issue.

ovidiuch avatar May 16 '17 04:05 ovidiuch

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

ovidiuch avatar May 16 '17 04:05 ovidiuch

It works @skidding!

marcioaffonso avatar May 16 '17 14:05 marcioaffonso

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

ovidiuch avatar May 19 '17 11:05 ovidiuch

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

scniro avatar May 25 '17 23:05 scniro

Bump! I'm having this issue too!

rocktavious avatar Jun 01 '17 13:06 rocktavious

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

scniro avatar Jun 01 '17 14:06 scniro

@scniro care to share your wrapper?

MrSauceman avatar Jun 01 '17 15:06 MrSauceman

@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

scniro avatar Jun 01 '17 16:06 scniro

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.

scniro avatar Jun 01 '17 17:06 scniro

I think I ran into this issue as well. I'm using redux, so I can monitor which values are present in the application state. The codemirror editor clearly does not reflect the value property that was given to it. However, I am unable to pin down the cases when this bug occurs; in some regions of my UI it works as expected, in others the editor doesn't update...

MartinHaeusler avatar Jun 02 '17 23:06 MartinHaeusler

I am having the same issue, this makes the library unusable for me. I downgraded for now.

arjanfrans avatar Jun 12 '17 13:06 arjanfrans

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

alexduf avatar Jun 12 '17 13:06 alexduf

would be awesome if this could be merged soon

stoplion avatar Jun 19 '17 00:06 stoplion

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!

ympadilha avatar Jun 24 '17 04:06 ympadilha

@JedWatson is there any schedule/plan to merge/fix this issue?

inoas avatar Jun 29 '17 18:06 inoas

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

besh avatar Jul 19 '17 18:07 besh

@hankthewhale thanks for the info. I downgraded the package a while ago. Overall I think that code-mirror is great, but to use it properly with react, we would need a full "controlled component" version that has no internal state and receives everything via props and callbacks. Unfortunately this wrapper here does not offer a lot of these features, and code-mirror in particular is quite a big component.

MartinHaeusler avatar Jul 19 '17 19:07 MartinHaeusler

@MartinHaeusler like I had mentioned earlier in this thread - react-codemirror2 is exactly as you describe - all through props and callbacks. I've recently updated the docs and demo site - give it a look.

scniro avatar Jul 19 '17 20:07 scniro

@marcioaffonso I think this lib only manages a focus state locally. Outside of the current bug for prop value comparison, it is fully controlled.

But yeah, other than downgrading or rolling your own, check out @scniro's lib.

besh avatar Jul 20 '17 01:07 besh

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

dandersonstack avatar Jul 21 '17 21:07 dandersonstack

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)~

inoas avatar Jul 24 '17 10:07 inoas

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.

laduke avatar Jul 28 '17 23:07 laduke

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

inoas avatar Oct 02 '17 16:10 inoas

const editor = document.querySelector('.CodeMirror').CodeMirror;
editor.setValue(STATE_VALUE);

lianghua1987 avatar Oct 06 '23 15:10 lianghua1987

ignore this... it's an issue I apparently subscribed to when logged in to valid8 github account years ago.


From: Huaaaaaa @.> Sent: Friday, October 6, 2023 08:04 To: JedWatson/react-codemirror @.> Cc: IT @.>; Manual @.> Subject: Re: [JedWatson/react-codemirror] Code mirror value doesn't update with state change in v1.0.0 (#106)

const editor = document.querySelector('.CodeMirror').CodeMirror; editor.setValue(STATE_VALUE);

— Reply to this email directly, view it on GitHubhttps://github.com/JedWatson/react-codemirror/issues/106#issuecomment-1750843606, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AD4VTZOOH33RMAR3LKT65N3X6AMZLAVCNFSM4DLNA2X2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZVGA4DIMZWGA3A. You are receiving this because you are subscribed to this thread.Message ID: @.***>

Caution: This email originated from outside Valid8. Do not click links or open attachments unless you recognize the sender and know the content is safe.

v8oss avatar Oct 06 '23 15:10 v8oss

just make a state , and in useEffect(()=>{setNewValue(value)},[value]) then add newValue to value in codeMirror i did and it worked perfectly

monir-shokohyan avatar Jul 04 '24 08:07 monir-shokohyan