React-ace: Problem mit Ass in der Feldkomponente von Redux-Form

Erstellt am 18. Dez. 2017  ·  6Kommentare  ·  Quelle: securingsincity/react-ace

Ich habe gerade ein ähnliches Problem wie https://github.com/securingsincity/react-ace/issues/120 .

Ich verwende React-Ace in Redux-Form als eine an Field übergebene Komponente.
Jedes Mal, wenn der Code-Editor den Fokus verliert, wird der Wert auf "" gesetzt und im Ass-Editor werden zwei Punkte angezeigt.

Mein Code ist genau wie jschlieber in der ursprünglichen Ausgabe vorgeschlagen, werfen Sie einen Blick darauf:

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}
        />
    )
}

und

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

kurz vor der Schaltfläche habe ich gerade einen Kommentar eingefügt, // if I put it here, then it suddenly works fine <ReduxAce/> - also ja, wenn ich den Ace Editor als nicht als Field-Komponente einsetze, dann wird sein Wert nicht gelöscht. Wie Sie sehen, habe ich versucht, den onBlur-Handler zu verwenden und den Wert beizubehalten, aber es gelang mir nicht.

Danke für jeden Hinweis!

awaiting response

Hilfreichster Kommentar

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}
    />
)

funktioniert bei mir gut

Alle 6 Kommentare

Ich habe das gleiche Problem. Ich sehe das Problem bei Version 5.1.1 , aber in 5.8.0 es ein Problem. Werde aktualisieren, wenn ich es herausfinden kann.

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}
    />
)

funktioniert bei mir gut

@drewen @spoonscen -

@avalkowsky - funktioniert der Vorschlag von @JFFby ? Der onBlur in Ihrem Beispiel übergibt den aktuellen Eingabewert an onBlur von reduxForm, der die Eingabe zurücksetzt, aber ich glaube nicht, dass dieser Wert während der Eingabe aktualisiert wird. Ich glaube, es gibt jedes Mal den __original__ Wert zurück, nicht den neuen Wert, den Sie gerade in den Editor eingegeben haben; Wenn Sie mit den benutzerdefinierten Komponenten arbeiten, können Sie mit zwei Zuständen arbeiten: den Redux-Form-Speicherdaten und den tatsächlichen Werten der Eingabe.

@drewen Ich gebe dir morgen ein paar Details!

@JFFby sorry, dass es so lange

Ihre Lösung funktioniert!

@drewen danke, das habe ich verpasst 👍

@taylordowns2000

Ich habe auch React-Ace auf 5.1.1 herabgestuft und es ohne onBlur-Callback versucht, aber es hat nicht funktioniert.
Vielleicht habe ich noch einen anderen Fehler gemacht, aber wenn ich ein Entwickler aus der Zukunft wäre, der auf dieses Problem stößt, würde ich JFFbys Lösung verwenden :)

Vielen Dank an alle für die Hilfe!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen