React-ace: doesn't play nice with redux-form

Created on 28 Jun 2016  ·  3Comments  ·  Source: securingsincity/react-ace

When used with redux-form, and onChange dispatches a "change" action, this causes AceEditor to re-render and places cursor at the end of editor.. preventing from making any changes

All 3 comments

@venil7 have you been able to integrate an ACE editor in a redux-form?
I have to do the exact same thing, could you provide some code sample please?

import React from 'react'
import AceEditor from 'react-ace'

export default function ReduxAce (props) {
  const {
    input,
    theme = 'github',
    mode = 'html',
    fontSize = 14,
    tabSize = 2,
    width = '1000px',
    height = '500px',
    ...custom
  } = props
  return (
    <AceEditor
      theme={theme}
      mode={mode}
      fontSize={fontSize}
      tabSize={tabSize}
      width={width}
      height={height}
      editorProps={{$blockScrolling: true}}
      {...input}
      {...custom}
    />
  )
}

and then use it:

import React from 'react'
import { reduxForm } from 'redux-form'
import ReduxAce from './path/to/ReduxAce'

function MyForm (props) {
  const { handleSubmit } = props
  return (
    <form onSubmit={handleSubmit}>
      <Field
        name='staticHtml'
        component={ReduxAce}
      />
    </form>
  )
}

export default reduxForm({
  form: 'edit-static-html',
  onSubmit (values, dispatch, props) {
    console.log('submit...')
  }
})(MyForm)

It's as simple as that and it works great!

I have a similar issue right now.

I am using react-ace inside redux-form, as a component passed to Field - just like above.
Anytime the editor loses focus, the value is set to "" and to dots are displayed inside the ace editor.

My code is just like jschlieber proposed, take a look:

`import React from 'react'
import AceEditor from 'react-ace'
import _ from 'lodash';

import 'brace/mode/javascript';
import 'brace/theme/monokai';

export default function ReduxAce (props) {
console.log(props.input.onBlur, props);

const {
    input,
    theme = 'monokai',
    mode = 'javascript',
    fontSize = 14,
    tabSize = 2,
    width = '1000px',
    height = '500px',
    ...custom
} = props;

return (
    <AceEditor
        theme={theme}
        mode={mode}
        fontSize={fontSize}
        tabSize={tabSize}
        width={width}
        height={height}
        onBlur={() => props.input.onBlur(props.input.value)}
        editorProps={{$blockScrolling: Infinity}}
        {...input}
        {...custom}
    />
)

}`

and

`import React, { Component } from 'react';
import { connect } from 'react-redux';
import { saveDraft } from '../actions/index';
import { bindActionCreators } from 'redux';
import { Field, reduxForm } from 'redux-form';
import ReduxAce from '../components/redux_ace'

const ID = 'id123', NAME = 'name123', SOME_CODE = 'code123';

function mapStateToProps({draft}) {
return {
draft
};
}

function mapDispatchToProps(dispatch) {
return bindActionCreators({
saveDraft
}, dispatch)
}

class Draft extends Component {

renderField(field) {
    return (
        <div className="form-group">
            <label>{field.label}</label>
            <input
                className="form-control"
                type="text"
                {...field.input}
            />
        </div>
    )

}

onSubmit(values) {
    console.log('sub',values);

    this.props.saveDraft({
        id: values[ID],
        name: values[NAME],
        code: values[SOME_CODE]
    });
}

render() {
    const { handleSubmit } = this.props;

    return (
        <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
            <Field
                label="Id"
                name={ID}
                component={this.renderField}
            />

            <Field
                label="Name"
                name={NAME}
                component={this.renderField}
            />
            <Field
                label="Lambda code"
                name={SOME_CODE}
                component={ReduxAce}
            />

            // if I put it here, then it suddenly works fine <ReduxAce/>
            <button type="submit" className="btn btn-primary"> Submit</button>
        </form>
    );
}

}

export default reduxForm({
validate,
form: 'DraftForm'
})(
connect(mapStateToProps, mapDispatchToProps)(Draft)
)`

just before the button I put a comment just now, " // if I put it here, then it suddenly works fine " - so yes, if I put the Ace Editor as is not as a Field component, then its value is not deleted. How you can see, I tried to use the onBlur handler and preserve the value, but I couldn't.

Thanks for any hints!

Was this page helpful?
0 / 5 - 0 ratings