Подтвердить что ты не робот

Каковы недостатки использования неизменяемого состояния в реактиве?

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

  • Состояние всех хранилищ хранится вместе в единой неизменной структуре данных.
  • Компоненты не имеют состояния, но имеют доступ к данным в их render() на основе функции хранения хранилища.
  • Магазины также являются апатридами, но изменяют состояние глобального приложения для своего домена с помощью курсора.
  • Компонент приложения верхнего уровня прослушивает изменения состояния и повторно отображает все дерево компонентов.
  • Компоненты реализованы как "чистые", что означает, что они должны использовать mustComponentUpdate для эффективного определения того, что они могут быть пропущены при повторном рендеринге.

Это упрощает структуру приложения несколькими способами:

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

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

Неизменяемость для меня нова, так же как и какие-либо предостережения, о которых я должен знать, если я начну использовать этот подход в сложном приложении реального мира?

Единственное, что я могу придумать, это использование forceUpdate(), поскольку Este использует его, поскольку я читал, что это синхронная функция. Например, Morearty, похоже, откладывает обновления к следующему кадру анимации для их пакетной обработки, но я рассматриваю это как детальную/оптимизационную реализацию, а не некоторую наследующую сторону подхода неизменяемого единого состояния.

4b9b3361

Ответ 1

Принятый ответ даже не начинает описывать существующие проблемы...

  • Документация. Некоторые из наиболее востребованных вопросов/заявлений в SO - это тривиальные вещи, такие как обновление вложенных элементов списка, потому что документация более ориентирована на аудиторию, знакомую с функциональным программированием, что делает ее менее доступной для остальных.
  • Это не тривиально, чтобы отделить знания иерархии модели от ваших компонентов. Мне не нравится делать this.state.getIn("[parent, child, index]") в компоненте, потому что это увеличивает возможность изменения модели, нарушающей код компонента. Это можно предотвратить с помощью расширяемости (подробнее об этом ниже) или с помощью вспомогательных методов, но вы, безусловно, потеряете простоту простых членов JS.
  • Значительная проблема, с которой я столкнулся, заключалась в том, чтобы иметь возможность сериализовать и де-сериализуйте состояние. Метод fromJS поддерживает настраиваемые реверсоры но они лаваш и требуют тщательного тестирования и обслуживания.
  • Тип записи сильно отстает от дебиляции, называемой вложением. Это печально, потому что это позволяет упростить (в относительном смысле) расширяемость, но поощряет только иерархию одного уровня. Вы не можете легко создавать вложенные записи из JSON. Это затрудняет их смешивание с регулярным неизменным использованием JS, если вы не используете вышеупомянутые регенераторы pita. И я упомянул о том, как печально, что, учитывая, что Records выставляют свойства модели в качестве членов первого класса, обеспечивают целостность модели и значения по умолчанию.
  • И тогда есть расширяемость. Попробуйте добавить помощников вокруг своих неизменных моделей данных, чтобы отвлечь зависимость иерархии модели в ваших компонентах, и вы готовы к заметной гонке с препятствиями. Де-сериализация становится битвой развода. Вам нужно будет возиться с ревнителями, если в "Рекордах" они будут плакать, и так далее. Более простой механизм расширяемости будет иметь большое значение для того, чтобы сделать мои компоненты более чистыми.
  • Никаких задокументированных передовых методов. Хотя это верно с №1, я все же должен упомянуть, что отсутствие хорошей документации не позволяет выбрать наилучший способ сделать что-то. Я не уверен, что я должен выбрать из программы обновления, или forEach или setIn (и так далее), чтобы обновить неизменяемую структуру. Методы не перекрестно ссылаются друг на друга, чтобы вы знали, какие альтернативы существуют.

Ответ 2

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

Единственным недостатком, который я обнаружил при использовании неизменяемых данных с React, является то, что инструменты разработчика React не очень хорошо работают с ними (они показывают базовую структуру данных неизменяемых значений вместо JS-friendly value).

Ответ 3

Я знаю, что ответ уже принят, но я считаю, что основным недостатком является то, что вы передаете не-простые объекты JavaScript в свой код компонента, то есть вы не можете использовать обычный JavaScript атрибуты свойств при чтении значений из объектов, не подлежащих передаче, через props. Вместо этого вы должны использовать API-интерфейс Immutable.js '. Это значительный компромисс. Вы не можете хранить свое использование Immutable.js, содержащегося там, где оно принадлежит, в магазине; он теперь просочился во все ваше приложение. Это боль, которую вы можете почувствовать, когда Immutable.js заменяется следующей библиотекой Immutability Buzzy, которая имеет собственный API или может использовать собственные атрибуты свойств. Кроме того, сторонний код почти наверняка ожидает простых старых объектов JavaScript, поэтому объекты Immutable должны быть преобразованы, прежде чем передавать их. Если вы планируете внедрить Immutable.js в существующее приложение, оно быстро станет неясным в вашем коде компонента, который props является неизменяемым и который является объектом JS, если вы не очень дисциплинированы и не придумали схему именования или какой-либо другой метод, с которым вы согласны, когда вы передаете объекты по цепочке рендеринга.