Реагировать компонентный рендер вызывается несколько раз при нажатии нового URL-адреса

Я создаю PhotoViewer, который меняет фотографии, когда пользователь нажимает влево или вправо. Я использую React, Redux, реактивный маршрутизатор и response-router-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 три раза. Думаю, это не имеет большого значения, потому что ничего не изменилось. Я новичок в этом наборе инструментов, поэтому не стесняйтесь задавать больше вопросов об этой проблеме.

Ответ 1

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

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

Ответ 2

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

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

(источник)

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

Ответ 3

У меня возникают похожие проблемы с использованием React и React Router. У меня есть Pure Component, который рендерит 4 раза. Я только устанавливаю состояние в методе commponentDidMount, но, похоже, все равно отображается. Я мог понять два раза, но четыре кажется чрезмерным.