I have a similar issue to https://github.com/securingsincity/react-ace/issues/120 right now.
I am using react-ace inside redux-form, as a component passed to Field.
Anytime the code editor loses focus, the value is set to "" and two dots are displayed inside the ace editor.
My code is just like jschlieber in the original issue 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 <ReduxAce/> - 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!
I've got the same issue. I don't see the problem with version 5.1.1, but in 5.8.0 it's an issue. Will update if I can figure it out.
const aceOnBlur = (onBlur) => (_event, editor?) => {
const value = editor.getValue();
onBlur(value);
};
...
return (
<AceEditor
className={className}
mode='html'
theme='monokai'
enableBasicAutocompletion={true}
showPrintMargin={false}
tabSize={4}
setOptions={options}
width='1000px'
name={input.name}
onBlur={aceOnBlur(input.onBlur)}
onChange={input.onChange}
onFocus={input.onFocus}
value={input.value}
/>
)
works fine for me
@drewen @spoonscen - Do either of you have suggestions on this as you guys have used redux-form in the past?
@avalkowsky - does @JFFby's suggestion work? The onBlur in your example passes the current input value to reduxForm's onBlur resetting the input, but I don't believe that value is updated as you type. I believe it's passing the __original__ value back each time, not the new value you just typed into the editor; when working with the custom components, you have two states to work with: the redux-form store data and the actual values on the input.
@drewen I'll give you some details tomorrow!
@JFFby sorry, that it took so long, shame on me.
Your solution is working!
@drewen thanks, I missed that 馃憤
@taylordowns2000
I also downgraded react-ace to 5.1.1 and tried it without onBlur callback but it was not working.
Maybe I made some another mistake, however if I was a developer from the future who run into this issue, I would use JFFbys solution :)
Thank you all for help!
Most helpful comment
works fine for me