Лучший метод проверки производительности, чтобы проверить, изменилось ли содержание ContentState в DraftJS или просто editorState

Я пытаюсь запустить функцию только тогда, когда изменился сам contentState, а не только editorState.

Моя идея сейчас заключалась бы в том, чтобы сохранить старое contentState в виде строки и сравнить его с новым contentState в виде строки, но преобразование состояний в строки и их сравнение кажется ужасно расточительным. Есть ли способ лучше?


person Slbox    schedule 27.08.2016    source источник
comment
если вы поделитесь кодом сравнения, мы можем помочь более подробно, если мой ответ вам не очень поможет   -  person Md.Estiak Ahmmed    schedule 27.08.2016


Ответы (3)


вы можете просто сравнить значение вашего old state и значение вашего new state, вам не нужно convert его с string.

РЕДАКТИРОВАТЬ: и вот концепция реакции state, о которой вам не нужно беспокоиться о large state object, поскольку лучшие практики рекомендуют делать это таким образом

Распространенное заблуждение: state содержится в large object. Это просто объект, ссылающийся на несколько других объектов. Ничего крупного в этом нет.

person Md.Estiak Ahmmed    schedule 27.08.2016
comment
Справедливое замечание, но по-прежнему кажется расточительным сравнивать этот относительно большой объект по каждому щелчку, нажатию клавиши и т. д. Я слишком много думаю об этом? Я знаю, что одна такая мелочь не убьет производительность, но кажется очень расточительной. Это наименее расточительный способ? - person Slbox; 27.08.2016
comment
нормально сравнивать их в таком случае, как вы упомянули для large object, когда нет простого способа update их с new state. - person Md.Estiak Ahmmed; 27.08.2016
comment
Обратите внимание, что поскольку они являются неизменяемыми объектами, сравнение выполняется быстро. Это сравнение идентичности, а не содержания. То есть this.state.editorState.getCurrentContent() === newEditorState.getCurrentContent() - person Ishmael Smyrnow; 14.02.2017
comment
Это не работает, если вы хотите исключить изменения состояния выбора и просто хотите сравнить состояние содержимого (блоки и объекты). - person Dmitry Minkovsky; 02.08.2018

Я использовал другой подход для проверки того, изменилось ли содержимое редактора или нет.

В основном я использую модуль npm deep-equal для сравнения необработанных объектов contentState (т.е. contentState преобразуется в простой объект JS с помощью функции convertToRaw). В обработчике onChange сравните старый и новый необработанные объекты contentState.

Примечание. Сравнение по модулю deep-equal примерно в 5 раз быстрее, чем обертывание узла assert.deepEqual() в try/catch.

Вот код обработчика onChange:

const deepEqual = require('deep-equal');

this.onChange = (editorState) => {

    let oldContent = convertToRaw(this.state.editorState.getCurrentContent());
    let newContent = convertToRaw(editorState.getCurrentContent());

    let sameContent = deepEqual(oldContent, newContent);

    this.setState({editorState});

    if (sameContent === false)
      console.log('Content has changed.');
}
person Faisal Mq    schedule 25.10.2016
comment
Это намного дороже, чем просто проверка ссылочного равенства, как это предлагается в ответе с наибольшим количеством голосов. - person Tarnay Kálmán; 20.12.2017
comment
Это единственный способ, если вы хотите учитывать только контент (блоки/сущности). - person Dmitry Minkovsky; 02.08.2018

Это не так уж отличается от ответа Фейсала Муштака, но включает в себя несколько улучшений. В вашем компоненте constructor:

// keep track of the last state
let lastContentState = this.state.editorState.getCurrentContent()

this.onChange = editorState => {
  this.setState({ editorState })

  // push your handling code onto the call stack with a setTimeout
  // so that it doesn't block handling new inputs to the editor
  setTimeout(() => {

    // first-time focus or blur, no change to content
    if (!editorState.getLastChangeType()) return

    const currentContentState = editorState.getCurrentContent()

    // ES6 to compare, could use Immutable.is() instead
    const toHandle = !Object.is(lastContentState, currentContentState)

    if (toHandle) {
      // your handler function, eg passed in as a prop
      this.props.handleChange(currentContent)

      // current content becomes last content
      lastContentState = currentContentState
    }

  }, 0)
}
person pfkurtz    schedule 10.12.2016