JedWatson / react-codemirror

Codemirror Component for React.js
MIT License
1.55k stars 262 forks source link

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

Open MrSauceman opened 7 years ago

MrSauceman commented 7 years ago

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.

marcioaffonso commented 7 years ago

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

ovidiuch commented 7 years ago

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 commented 7 years ago

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

marcioaffonso commented 7 years ago

It works @skidding!

ovidiuch commented 7 years ago

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

scniro commented 7 years ago

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

rocktavious commented 7 years ago

Bump! I'm having this issue too!

scniro commented 7 years ago

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

MrSauceman commented 7 years ago

@scniro care to share your wrapper?

scniro commented 7 years ago

@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 commented 7 years ago

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.

MartinHaeusler commented 7 years ago

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

arjanfrans commented 7 years ago

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

alexduf commented 7 years ago

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

stoplion commented 7 years ago

would be awesome if this could be merged soon

ympadilha commented 7 years ago

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!

inoas commented 7 years ago

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

besh commented 6 years ago

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

MartinHaeusler commented 6 years ago

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

scniro commented 6 years ago

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

besh commented 6 years ago

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

dandersonstack commented 6 years ago

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

inoas commented 6 years ago

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

laduke commented 6 years ago

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.

inoas commented 6 years ago

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

lianghua1987 commented 9 months ago
const editor = document.querySelector('.CodeMirror').CodeMirror;
editor.setValue(STATE_VALUE);
v8oss commented 9 months ago

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.

monir-shokohyan commented 3 days ago

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