React-ace: setState в onChange заблокирует редактор

Созданный на 22 мар. 2017  ·  13Комментарии  ·  Источник: securingsincity/react-ace

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

Самый полезный комментарий

@mbrochstein Мне удалось найти обходной путь с помощью метода Reacts shouldComponentUpdate.

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

Затем для моего метода onChange для

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

Это обновит состояние aceEditorValue с учетом того, что введено в редактор, без повторного рендеринга всего компонента. Работает для моего варианта использования.

Все 13 Комментарий

У меня, как мне кажется, похожая проблема. Я помещаю текстовое содержимое редактора в состояние и устанавливаю value для текста, который находится в состоянии.

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

Однако это не работает должным образом. Я думаю, что редактор повторно инициализируется на каждом этапе, что не очень хорошо :(

Я все еще точно работаю над тем, что происходит.

Я думаю, что корень проблемы в том, что если вы меняете текст, компонент всегда обновляется.

Одним из решений было бы добавить shouldComponentUpdate() который обновляется только при изменении свойств ИЛИ когда текстовое свойство не равно тексту, отображаемому в редакторе.

или нет, видимо до сих пор не совсем понимаю: grin:

У меня похожая проблема

редактировать:
Я нашел способ решения моей конкретной проблемы.
У меня возникли проблемы с попыткой записать ввод с помощью setState.
Похоже, что наличие defaultValue вызывало какой-то конфликт. (что, я полагаю, имеет смысл?)
Вместо этого я использовал value а теперь onChange, и редактор работает так (по крайней мере, как я) ожидал.

Не уверен, что это то, что испытывали @mjmdavis и @ dyf102 .

Я всегда использовал слово «ценность». Думаю, я просто вел себя глупо.

Кто-нибудь найдет решение этой проблемы?

У меня такая же проблема.

@mbrochstein Мне удалось найти обходной путь с помощью метода Reacts shouldComponentUpdate.

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

Затем для моего метода onChange для

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

Это обновит состояние aceEditorValue с учетом того, что введено в редактор, без повторного рендеринга всего компонента. Работает для моего варианта использования.

@brendanmcgivern Спасибо! Я думаю, вы перевернули свои компараторы в функции shouldComponentUpdate , но как только я переключил ее на === , она работает отлично!

Что насчет этого? Это хорошо работает в моем проекте.

РОДИТЕЛЬСКИЙ КОМПОНЕНТ

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

РЕДАКТОР

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

Так что вопрос здесь мы выстукивать в ace фактического редактора change события , а не слушать и перерисовку. Похоже, вы хотите иметь возможность использовать период времени, когда происходят изменения. У нас может быть еще одна ловушка в componentWillReceiveProps которая предотвращает обновление. Лично я считаю, что решение @brendanmcgivern является самым чистым.

Такая же проблема здесь: /

Что ж, это огромная ошибка, и она все еще существует.
Я пытался использовать react-ace с https://github.com/jaredpalmer/formik, и поведение такое же, просто зависает.

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

UPD
Выглядит не очень красиво, но у меня получилось. Ключевой проблемой, насколько я понимаю, является то, что вам лучше не устанавливать состояние и ничего не делать со значением прямо из onChange (inline) у туза. Лучше сделать это в функции другого компонента.

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>;
  }
}

Была ли эта страница полезной?
0 / 5 - 0 рейтинги