Search code examples
javascriptnode.jsreactjscodemirrorreact-codemirror

react-codemirror beforeChange event


I am using react-codemirror node module as follows:

<CodeMirror 
  className={className} 
  value={this.state.code} 
  onBeforeChange={this.onBeforeChange} 
  onChange={this.onChange} 
  options={options}
/>

The change event works fine, but I can't seem to hook up with the beforeChange event. Anyone know what I am doing wrong?

I have declared handlers in my class as follows:

onBeforeChange(change) {
  console.log('calling beforeChange');
}

onChange(newCode) {
  this.setState({
    code: newCode
  });
}

Solution

  • Author of react-codemirror2 here. I stumbled upon your question and wanted to follow up with a detailed answer as there are some breaking changes in 3.x. The component now ships with an UnControlled and Controlled variant based on different use cases. I see you are calling setState within the onBeforeChange callback. In your case, I'd suggest leveraging the controlled component as such...

    import {Controlled as CodeMirror} from 'react-codemirror2'
    
    <CodeMirror
      value={this.state.value}
      options={options}
      onBeforeChange={(editor, data, value) => {
        this.setState({value}); // must be managed here
      }}
      onChange={(editor, metadata, value) => {
        // final value, no need to setState here
      }}
    />
    

    With the controlled variant, managing state is required on the value prop to see any changes.

    Additionally, the UnControlled component also has an onBeforeChange callback as well, yet with different behavior as such...

    import {UnControlled as CodeMirror} from 'react-codemirror2'
    
    <CodeMirror
      value={value}
      options={options}
      onBeforeChange={(editor, data, value, next) => {
        // hook to do whatever
        next();
      }}
      onChange={(editor, metadata, value) => {
      }}
    />
    

    Here however, onChange will be deferred until next is invoked if onBeforeChange is specified. If not, onChange will fire regardless. Important to note, though, with the UnControlled variant, the editor will always react to input changes - the difference will simply be if onChange is called or not.

    These changes were inspired due to the needs of the community and I encourage you to open an issue should anything not be working as you expect.