Вопрос по react-router, javascript, rea,ctjs, redux – React компонент рендеринга вызывается несколько раз при нажатии нового URL

21

Я строю PhotoViewer, который меняет фотографии, когда пользователь нажимает влево или вправо. Я использую React, Redux, реакции-маршрутизатор и реагирует-маршрутизатор-редуктор. Когда пользователь нажимает влево или вправо, я делаю две вещи, я обновляю URL, используяthis.context.replace() и я отправляю действие для обновления просматриваемой фотографии,this.props.dispatch(setPhoto(photoId)), Я подписываюсь на изменения состояния для отладки.

Каждая из приведенных выше строк вызывает новое изменение состояния. Отправка действия обновляет магазин, так как я обновляюcurrentlyViewedPhoto и обновление URL-адреса обновляет хранилище, так как response-router-redux обновляет URL-адрес в хранилище. Когда я отправляю действие, в первом цикле рендеринга компонентrender Функция вызывается дважды. Во втором цикле рендеринга компонентrender Функция вызывается один раз. Это нормально? Вот соответствующий код:

class PhotoViewer extends Component {
  pressLeftOrRightKey(e) {
    ... code to detect that left or right arrow was pressed ...

    // Dispatching the action triggers a state update
    // render is called once after the following line
    this.props.dispatch(setPhoto(photoId)) // assume photoId is correct

    // Changing the url triggers a state update
    // render is called twice
    this.context.router.replace(url) // assume url is correct
    return
  }

  render() {
    return (
      <div>Test</div>
    )
  }
}

function select(state) {
  return state
}

export default connect(select)(PhotoViewer)

Это нормально, что рендер вызывается три раза? Это кажется излишним, потому что React должен будет выполнить DOM три раза. Я думаю, это не будет иметь большого значения, потому что ничего не изменилось. Я новичок в этом наборе инструментов, поэтому не стесняйтесь задавать дополнительные вопросы по этой проблеме.

У меня была проблема с отсутствием косых черт в моих ссылках. Если бы у меня было<Link to="foo">, React роутер (не использует Redux) "перенаправил" из#foo в#/foo и вызывая дополнительный рендер. Добавление косой черты в ссылку исправило ее. Это использует hashHistory. Marc Stober

Ваш Ответ

2   ответа
16

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

Изменить: Вы также можете посмотреть на расширениеReact.PureComponent вместоReact.Component если вам нужно только поверхностное сравнение в вашемshouldComponentUpdate метод жизненного цикла. Больше информацииВот.

Я тоже новичок в React и был удивлен, чтоrender() звонили дважды, и о, кстати, переключаясь наPureComponent без разницы :( George Jempty
Приятно знать, что это нормально. Это мой первый раз, когда я использую эту архитектуру, и меня действительно беспокоило, что рендер запускался несколько раз. egidra
Абсолютно понятно - для такой ситуации вы действительно не начнете видеть проблемы с производительностью, пока не получите очень сложные компоненты. Donald
17

Если вы устанавливаете состояние на трех разных этапах, компонент также будет повторно визуализироваться три раза.

setState () всегда будет запускать повторную визуализацию, если логика условной визуализации не реализована в shouldComponentUpdate ().

(источник)

Вы можете реализовать логику вshouldComponentUpdate () чтобы предотвратить ненужные повторные рендеры, если у вас возникли проблемы с производительностью.

Лично я не использовал response-router-redux, поэтому я не могу, к сожалению, ответить на это. Вы можете попробовать записать изменения состояния внутри вашего магазина илиshouldComponentUpdate и посмотрим, что меняется. villeaka
Я мог бы понять, если бы было два повторных рендеринга (от действия рассылки и замены URL), но три из них имеют отношение ко мне. Замена URL вызывает два обновления, а не одно. Реакция-маршрутизатор-редуктор делает два обновления в магазине или что-то? egidra
Я считаю это неоправданным. Самоуспокоенность с «просто запустите все, что угодно, с тем же количеством аргументов и результатов, если только у вас не возникнет проблема» grantwparks

Похожие вопросы