React-ace: setState en onChange bloqueará el editor

Creado en 22 mar. 2017  ·  13Comentarios  ·  Fuente: securingsincity/react-ace

  onChange(newValue) {
    this.setState({ code: newValue });
    console.log('change', this.state.code);
  }
bug help wanted

Comentario más útil

@mbrochstein Pude encontrar una solución mediante el método Reacts shouldComponentUpdate.

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.aceEditorValue !== nextState.aceEditorValue) {
      return false
    } else {
      return true;
    }
  }

Luego, para mi método onChange para el

onChange = (newValue) => {
    this.setState({
      aceEditorValue: newValue
    });
  }

Esto actualizará el estado de aceEditorValue con lo que se ingrese en el editor sin volver a renderizar todo el componente. Funciona para mi caso de uso.

Todos 13 comentarios

Tengo lo que creo que es un problema similar. Pongo el contenido de texto del editor en el estado y configuro value en el texto que está en el estado.

<AceEditor
    value={this.state.text}
    onChange={(newValue) => this.textChanged(newValue)}/>

Sin embargo, esto no funciona correctamente. Creo que el editor se reinicializa en cada paso, lo cual no es muy bueno :(

Todavía estoy trabajando exactamente en lo que está pasando.

Creo que la raíz de este problema es que si cambia el texto, el componente siempre se actualiza.

Una solución sería agregar un shouldComponentUpdate() que solo se actualice cuando las propiedades hayan cambiado O cuando la propiedad del texto no sea igual al texto que se muestra en el editor.

o no, aparentemente todavía no entiendo esto: sonrisa:

Tengo un problema similar

editar:
Encontré una solución para mi problema particular.
Tenía problemas al intentar capturar la entrada usando un setState.
Parece que tener un defaultValue estaba causando algún tipo de conflicto. (que tiene sentido, supongo?)
Usé value lugar y ahora onChange y el editor funciona como (al menos como yo) esperaba.

No estoy seguro de si esto es lo que estaban experimentando @mjmdavis y @ dyf102 .

Siempre estaba usando 'valor'. Creo que solo estaba siendo tonto.

¿Alguien encuentra una solución para este problema?

Tengo el mismo problema.

@mbrochstein Pude encontrar una solución mediante el método Reacts shouldComponentUpdate.

shouldComponentUpdate(nextProps, nextState) {
    if (this.state.aceEditorValue !== nextState.aceEditorValue) {
      return false
    } else {
      return true;
    }
  }

Luego, para mi método onChange para el

onChange = (newValue) => {
    this.setState({
      aceEditorValue: newValue
    });
  }

Esto actualizará el estado de aceEditorValue con lo que se ingrese en el editor sin volver a renderizar todo el componente. Funciona para mi caso de uso.

@brendanmcgivern ¡Gracias! Creo que invirtió sus comparadores en la función shouldComponentUpdate , pero una vez que cambié eso a === , ¡funciona perfectamente!

¿Y este? Funciona bien en mi proyecto.

EL COMPONENTE PADRE

    // other methods ...
    eventMDChange(value) {
        let _html = Marked(value)
        this.setState({ markdown: value, html: _html })
    }
    // other methods ...

EL EDITOR

<AceEditor
    onChange={ (raw)=>{this.eventMDChange(raw);} }
    value={ this.state.markdown }
    />

Así que la cuestión aquí es que estamos aprovechando ace real del editor de change evento en lugar de escuchar y rerendering. Parece que desea poder aprovechar el período de tiempo en el que se está produciendo un cambio. Podríamos tener otro gancho en componentWillReceiveProps que impida una actualización. Personalmente, creo que la solución de @brendanmcgivern es la más limpia.

El mismo problema aquí: /

Bueno, este es un error enorme y todavía está ahí.
Intenté usar react-ace con https://github.com/jaredpalmer/formik y el comportamiento es el mismo, simplemente se atasca.

<AceEditor
mode="yaml"
theme="solarized_light"
onChange={value => {
  setFieldValue("content", value);
}}
tabSize={2}
editorProps={{ $blockScrolling: true }}
value={''}
width="100%"
/>

upd
Esto no se ve bien, pero funcionó para mí. La cuestión clave, según tengo entendido, es que es mejor que no establezcas el estado ni hagas nada con el valor desde el onChange del as (en línea). Será mejor que lo hagas en la función de los diferentes componentes.

import React, { Component } from "react";
import { Formik, Form, Field } from "formik";

class AcePlusFormik extends Component {
  state = { content: "" };

  /**
   * Special treatment for ace content
   * <strong i="15">@param</strong> {string} value
   */
  setContent(value) {
    this.setState({ content: value });
    this.setFieldValue("content", value);
  }

  render() {
    <Formik
      initialValues={{ title: "", content: "" }}
      onSubmit={values => console.log(values)}
    >
      {({ touched, setFieldValue }) => {
        this.setFieldValue = setFieldValue;
        return (
          <Form>
            <Field name="content">
              {({ field }) => (
                <React.Fragment>
                  <AceEditor
                    mode="yaml"
                    theme="solarized_light"
                    onChange={value => {
                      this.setContent(value);
                    }}
                    tabSize={2}
                    editorProps={{ $blockScrolling: true }}
                    value={this.state.content}
                    width="100%"
                  />
                  <input type="hidden" {...field} />
                </React.Fragment>
              )}
            </Field>
            <button
              className="button is-primary is-pulled-right"
              style={{ marginTop: "10px" }}
              type="submit"
            >
              Save
            </button>
          </Form>
        );
      }}
    </Formik>;
  }
}

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

huangjiatian picture huangjiatian  ·  7Comentarios

ghiden picture ghiden  ·  3Comentarios

dmavrin picture dmavrin  ·  3Comentarios

avalkowsky picture avalkowsky  ·  6Comentarios

henviso picture henviso  ·  7Comentarios