2015-03-20 2 views
8

Я создаю Word Dojo клон в React/Flux. Игра по сути Boggle - вы делаете слов, нажав на соседних букв в сетке:Вложенная петля Реагирует на компоненты с Flux, change-listeners на родителях или на детей?

enter image description here

Моя React компоненты с их источником:

  1. Gameboard
  2. TileColumn
  3. Tile

Весь исходный код can be viewed here.


Как это прямо сейчас работает:

Там в GameStore, который содержит двумерный массив из яваскрипта объектов. объекты имеют строковое значение «буква» и «активное» логическое значение. Когда пользователь нажимает на письмо, которое отправляется в GameStore, который обновляет этот двухмерный массив и испускает событие Change.

Компонент GameBoard прослушивает это событие изменения, а затем повторно отображает 10 TileColumns, которые, в свою очередь, отображают 10 Tiles каждый. GameBoard имеет данные магазина как часть своего состояния, а плитки имеют собственную букву/активный статус в качестве реквизита.

Проблема в том, что изменение 1 буквы заставляет все 100 плиток перерисовываться.


shouldComponentUpdate

Я попытался с помощью shouldComponentUpdate на плитки, чтобы указать, что он должен обновлять только если его «активным» значение изменилось, но проблема в том, что оба this.props.active и nextProps .активные всегда имеют одно и то же значение: либо они оба ложные, либо оба истины.


Отсрочка ответственность детей

Другая идея у меня было, чтобы каждый Tile ответственность за свое собственное обновление, путем регистрации изменений слушателей на плитку непосредственно. У меня появилось предупреждение, что я превысил количество слушателей, и это похоже на 100 слушателей с изменениями, и все стрельбы по каждому обновлению букв будут менее эффективными. Несмотря на то, что это все только Javascript, поэтому мы бы избежать некоторых DOM манипуляции ...


Performance

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


Помощь нужна

Конкретно я ищу советы о наилучшей практике в этой ситуации (когда у вас есть вложенные, итерация компоненты), и если shouldComponentUpdate является решение, но я просто используя это неправильно.

Спасибо!

ответ

12

Да, это классический пример того, почему React не работает по умолчанию. У меня довольно длинный пример here для какой именно проблемы вы пытаетесь решить.

В основном у вас есть две типичные проблемы:

  1. Как вы initialize the tiles on the board это хорошо, но как вы modify the values for the tile просто мутирует объект. Это затрудняет определение того, изменился ли какой-либо объект.

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

Решение:

shouldComponentUpdate Использования (или просто использовать ReactComponentWithPureRenderMixin), чтобы предотвратить расточительный перерасчет в Tile. Конечно, этот не будет работать, если вы не выполните несколько вещей.

Solutions являются:

  1. Вы знаете, какие свойства могут быть мутировал и настроить shouldComponentUpdate на основе тех.

Только tile.active разрешено менять шрифт? Возможно, вы сможете просто define your callback, чтобы вы только проверяли равенство prevProps.tile.active === this.props.tile.active.

  1. Создайте новый объект, чтобы неглубоко сравнивать ссылки на объекты.

Вы, наверное, уже знаете, что var a = {}; var b = a сделает это так, что a === b, и что var c = {}; var d = {}; сделает это так, что c !== d. Замените объект плитки полностью, когда вы делаете обновления, чтобы вы могли использовать новый объект плитки, где был старый. Таким образом, быстрая производительность - это буквально только mixins: [ReactComponentWithPureRenderMixin].

Это может быть больше дерьма, чем вы хотели, но это в значительной степени, как я получаю любую коллекцию, чтобы хорошо отразить реакцию. Без этих методов я буквально не могу получить my crappy etch-a-sketch component, чтобы работать, не останавливаясь.

Удачи вам!

+0

Вы также должны поместить чек в mustComponentUpdate TileColumn. И ImmutableJS упрощает работу с PureRenderMixin.Переключитесь на ImmutableData, используйте mixin во всех ваших компонентах, и все готово. – fisherwebdev

+0

Спасибо! Это было очень полезно. Я почти уверен, что причина shouldComponentUpdate не работала из-за переменных javascript-just-point-to-objects; использование Immutable.js должно исправить это, и это то, что я хотел сделать в любом случае. –

Смежные вопросы