React сжимает рендеринг, вызывая не обновление компонентов, даже если вызван componentDidUpdate - PullRequest
0 голосов
/ 01 января 2019

Процесс рендеринга родительского компонента React автоматически сжимает рендеринг дочерних компонентов.Это может быть повышение производительности для большинства приложений, но такая ситуация может быть серьезной проблемой.

У меня есть 2 компонента:

  1. Компонент боковой панели списка файлов
  2. Компонент текстового редактора (сейчас я использую Slate)

Два компонента являются дочерними компонентами компонента Home.

Когда пользователь щелкает элемент боковой панели, он должен:

  1. Выделите выбранный элемент
  2. Установите новое состояние редактора, прочитав текстовый файл

Второй шаг может стать узким местом.Проблема в том, что React тупо сжимает разделенные две операции.Это приводит к тому, что пользователь не может видеть выделение элемента сразу после нажатия!Пользователь должен дождаться чтения файла и установить новое состояние редактора, а затем, наконец, элемент может быть выделен.

Эта задержка плохо влияет на работу пользователя.Вы когда-нибудь использовали текстовый редактор, который реагирует на ваш щелчок примерно через 500 мс?Программа выглядит «медленнее».

componentDidUpdate(prevProps) {
    console.log('componentDidUpdate!');
    const { currentDir, actions, currentFile } = this.props;
    if (prevProps.currentDir !== currentDir) {
      updatedFileList(currentDir);
    } else if (prevProps.currentFile !== currentFile) {
      updateEditorContent(currentFile);
    }
  }

Это компонент DidUpdate.Это обновляет состояние редактора.

redux-logger.js:1  action SELECT_FILE_LIST_ITEM @ 21:29:18.332
21:29:18.338 redux-logger.js:1  action UPDATE_CURRENT_FILE @ 21:29:18.338
21:29:18.347 Home.js:287 render!!
21:29:18.356 Home.js:44 componentDidUpdate!
21:29:18.366 redux-logger.js:1  action UPDATE_EDITOR_CONTENT @ 21:29:18.357
21:29:18.373 Home.js:287 render!!
21:29:18.678 Home.js:44 componentDidUpdate!

В журнале говорится, что оно componentDidUpdate d при 21:29:18.356, но фактический HTML DOM еще не обновлен.Он автоматически обновляет DOM после 21:29:18.678 Home.js:44 componentDidUpdate!. '

Как разделить два компонента DidUpdates, чтобы отдельно обновить DOM?

1 Ответ

0 голосов
/ 01 января 2019

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

componentDidUpdate(prevProps) {
    console.log('componentDidUpdate!');
    const { currentDir, actions, currentFile } = this.props;
    if (prevProps.currentDir !== currentDir) {
      updatedFileList(currentDir);
    } else if (prevProps.currentFile !== currentFile) {
      setTimeout(()=>{updateEditorContent(currentFile);}, 0);
    }
  }

Я на самом деле не пробовал это, поэтому я прошу прощения, если есть какие-либо синтаксические проблемы.

В общем, то, что делает React, желательно - не тратить время на обновление DOM два раза, когда одно обновление состояния немедленно запускает другое обновление состояния.Это позволяет избежать мерцания DOM, когда оба обновления происходят быстро.

React может сделать это, потому что он разбивает свою работу на две фазы

  • фаза рендеринга / согласования, в которой React определяет, что должно быть изменено при следующем обновлении DOM
  • фаза фиксации, когда эти обновления фактически применяются к DOM

Когда рендеринг запускает другой рендеринг, React задерживается на фазе фиксации и пакетирует обновления DOM для одногосовершить.Приведенное выше setTimeout приведет к тому, что это обновление состояния будет ждать до завершения фазы фиксации для первого обновления.

Я думаю, что будущие функции React в асинхронном режиме предоставят более удачные способы борьбы с такого рода сценарием, когда одно обновлениеимеет высокий приоритет, а другой имеет более низкий приоритет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...