Redux: Запрос на обсуждение: "шаблон" Redux, кривая обучения, абстракция и самоуверенность

Созданный на 19 мар. 2017  ·  108Комментарии  ·  Источник: reduxjs/redux

Решение: используйте Redux Starter Kit

Идеи из этой ветки в конечном итоге превратились в наш новый пакет Redux Starter Kit . Он включает в себя утилиты для упрощения многих распространенных вариантов использования Redux, включая настройку хранилища, определение редуктора, неизменяемую логику обновления и даже автоматическое создание целых «фрагментов» состояния без написания каких-либо создателей действий или типов действий вручную.

Для получения более подробной информации о том, какие проблемы Redux Starter Kit предназначен для решения (и чего он _ не будет), смотрите манифест «Vision for Redux Starter Kit», который я написал .

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

Я только что обсудил с @tannerlinsley несколько из этих аспектов. Мы обсудили библиотеку Jumpstate , которая представляет собой слой абстракции вокруг Redux, и то, как она была предназначена для облегчения кривой обучения, а также различные философские мнения о том, что составляет «хорошее» использование Redux.

В результате у нас возникло несколько вопросов, которые я хотел бы поднять для более широкого обсуждения:

Ключевые моменты

Boilerplate / многословие

  • Redux не предназначен для того, чтобы быть «наиболее кратким способом решения задач», а скорее для того, чтобы сделать поток данных очевидным и читаемым.
  • Документы написаны в преднамеренно подробном стиле для ясности и обучения, и специально не задумывались как «единственный верный способ написания кода Redux», но этот стиль был несколько слепо принят (или, иногда, приводил к отказу от Redux)
  • Частые жалобы на "шаблон", например "слишком много файлов", "использование создателей действий" и т. Д.

Абстракции и обучение

  • Сама основная библиотека Redux является полнофункциональной, но сообщество создает множество интересных дополнений и инструментов.
  • Были созданы различные библиотеки абстракции, чтобы «упростить обучение» или «сделать вещи более ООП», но большинство из них на самом деле не является «идиоматическим» использованием Redux.
  • Кривая обучения Redux может быть крутой, но как только вы поймете концепции, необходимость в слоях абстракции часто отпадает.

Проблемы

  • К чему в основном относятся "шаблонные" жалобы?
  • Каковы самые сложные аспекты Redux для новичков?
  • Какие области «без мнений» вызывают у людей проблемы?

Возможные решения

  • Как будет выглядеть идиоматическое использование Redux с «менее шаблонным»? Как мы можем решить эти жалобы?
  • Какие возможные абстракции можно было бы создать, чтобы упростить процесс обучения и использования, но без фактического сокрытия Redux (и, надеюсь, предоставит путь миграции / обучения к «базовому» Redux)?
  • Насколько из этого можно как-то решить улучшенную документацию?

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

Самый полезный комментарий

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

  • Подмножество, удобное для Flow / TypeScript, которое легче набирать, чем ванильный Redux.
  • Не особо выделять константы (просто сделайте безопаснее использование строковых литералов).
  • Сохранение независимости от React или других библиотек представлений, но упрощение использования существующих привязок (например, предоставление реализаций mapStateToProps ).
  • Сохранение принципов Redux (сериализуемые действия, путешествия во времени и горячая перезагрузка должны работать, журнал действий должен иметь смысл).
  • Поддержка разделения кода более простым способом из коробки.
  • Поощрение объединения редукторов с селекторами и упрощение их совместного написания (подумайте о связках редуктор-селектор, которые легко писать и составлять).
  • Вместо того, чтобы объединять создателей действий с редукторами, полностью избавиться от создателей действий и сделать сопоставление действий-редукторов «многие-ко-многим» естественным (вместо того, чтобы уклоняться от этого, как это делают большинство библиотек).
  • Принятие разумных значений производительности по умолчанию, чтобы мемоизация с помощью Reselect «просто работала» для распространенных случаев использования, когда пользователи не писали этот код.
  • Содержит встроенные помощники для индексирования, нормализации, коллекций и оптимистичных обновлений.
  • Имея встроенную поддержку тестируемого асинхронного потока.

Разумеется, поверх ядра, хотя можно назвать его официальным Redux.
Кроме того, я не буду писать об этом. Но ты можешь.

Все 108 Комментарий

Несколько идей:

  • официальный пакет redux-preset, содержащий redux, react-redux, redux-thunk, уже соединенные вместе
  • dispatch(actionType, payload) может снизить потребность в создателях действий
  • встроенные создатели редукторов в стиле jumpstate, например createReducer({[actionType]: (state, payload) => state}, initState)

Большинство людей, которых я знаю, которые активно используют redux, в конечном итоге отходят от redux-thunk, поскольку они обнаруживают, что он не очень хорошо масштабируется, и в конечном итоге приводит к создателям действий, которые начинают делать слишком много и вместо этого используют что-то другое для управления стороной. -эффекты, такие как redux-observable или redux-saga.

Я могу понять его привлекательность, особенно когда приступаю к работе с redux, но я не уверен, что лучше всего было бы объединить его как часть «стандартного пакета лучших практик».

Итак, эта часть для меня более важна (это будут не столько идеи для решения проблемы, а скорее ограничения, которые, по крайней мере, для меня, важны):

Redux не предназначен для того, чтобы быть «наиболее кратким способом решения задач», а скорее для того, чтобы сделать поток данных очевидным и читаемым.

В Redux замечательно то, что это больше похоже на шаблон проектирования, чем на фреймворк, и весь код, который вы видите (кроме магазина и react-redux ), является вашим собственным.

Глядя на Jumpstate (я не знал об этом до сих пор), это один из первых уровней абстракции, которые я вижу для Redux, который выглядит хорошо. Даже здорово! Но в то же время он лишь на волосок отличает вас от других фреймворков, таких как MobX, а наличие нескольких фреймворков, которые вносят одно и то же в таблицу, не очень полезно. Поэтому важно сосредоточиться на том, что отличает Redux от остальных, а не только на том, как мы можем сделать Redux лучше в вакууме (потому что он живет в том же мире, что и другие инструменты).

Еще одна важная вещь заключается в том, что у новичков возникает множество проблем, когда они сталкиваются с Redux, это не сам Redux, а JavaScript. Другие крупные фреймворки, такие как Angular, абстрагируются от самого JavaScript. Написание редуктора Redux - это просто применение ванильных «шаблонов проектирования» javascript, которые могут быть не знакомы новичкам, и заставят людей вместо этого использовать черный ящик.

Наконец, многие стандартные библиотеки сокращения пытаются добавить соотношение 1: 1: 1 между компонентами, редукторами и создателями действий (возможно, не всеми тремя, но часто двумя из них), что заставляет новичков забыть, что у них может быть несколько редукторов, обрабатывающих действие. , несколько компонентов, использующих состояние из нескольких редукторов, и так далее. Это один из вопросов №1, на который я отвечаю на работе и в других местах, и он очень полезен. Так что инструмент, помогающий в этой области, не должен потерять это (к тому же «переключатели неприятны» - не лучший аргумент в мире).

Итак, ИМО, призывы к действию будут включать в себя ссылку на хорошие ванильные ресурсы JavaScript, а также документирование большего количества «почему» прямо вместе с концепцией «начало работы» и упрощение вещей. Вы можете создавать гигантские приложения в Redux, вообще не изучая много новых концепций. Хотя я сам наблюдаю за редукцией, я видел несколько сотен тысяч строк кода приложений, использующих Thunk без проблем (и я видел, как крошечные приложения разваливались с помощью thunk). Очень помогает представление очень немногих «основных» концепций и демонстрация того, как их можно применить к множеству концепций.

«Все шаблоны должны быть сокращены независимо от затрат» - это проблема сообщества разработчиков программного обеспечения в целом в наши дни ... с этим труднее справиться.

С самого начала моя основная проблема с сокращением заключалась в том, что либо я читаю, либо пишу код, мне приходилось переключаться между N файлами, b / c логика одной части пользовательского интерфейса разбросана по всей кодовой базе между действиями, типами действий и несколькими редукторы. Мне очень нравится, что я могу обращаться к любой части дерева состояний из любого места в пользовательском интерфейсе, и я могу изменять различные части состояния в ответ на одно действие (основные причины, по которым я использую redux), но больше частей состояние, которое я изменяю в ответ на одно действие, тем больше размывается моя логика. Я не могу просто прочитать или написать, что произошло, когда пользователь сделал то или это. Но то, что я хочу, можно описать так:

// meta code
dispatch(ACTION);

onAction = {
  ACTION: [
    // handler 1: hide spinner here,
    // handler 2: change status there,
    // handler 3: update entity
  ],
};

В конце концов, я придумал redux-interactions + redux-tree и я очень доволен этим.

Подход в нашем текущем проекте:

обратите внимание, будет сильно отличаться в зависимости от требований приложения :) как только мы добавим обновления объектов в реальном времени, возможно, саги или наблюдаемые будут иметь преимущество перед thunk / обещанием

  • редукционный преобразователь
  • обещать промежуточное ПО
  • наша "оболочка api", которая представляет собой оболочку для клиентского приложения, service(name, method, ...opts) которая является создателем действия с полезной нагрузкой, являющейся обещанием вызвать наш API (т.е. промежуточное ПО обещания подбирает его и отправляет x_FULFILLED , x_PENDING и x_REJECTED ). также можно было перезаписать название действия для этого.

Сначала мы используем componentDidMount() для вызова нашего API, сохраняем данные в состоянии компонента. Тем не менее, мы используем для этого нашу оболочку api, что означает, что действие все еще отправляется (и регистрируется промежуточным программным обеспечением регистратора, включая мета, которая является информацией запроса), и если мы так желаем реорганизовать использование хранилища для этого компонента, все, что нам нужно в это добавить редуктор, который прослушивает действие. Мы начинаем с использования только локального состояния и реорганизуем его в redux, когда к состоянию этого компонента нужно получить доступ / изменить из другого компонента. При этом я вижу привлекательность использования redux повсюду, поскольку он обеспечивает бумажный след для всего. Учитывая нашу текущую команду и сроки подачи заявок, это просто невыгодно для нас, банкомат.

Я немного поиграл с redux-saga, но, поскольку наш самый сложный асинхронный поток - это вход / выход, который работает (и код не очень сложен), не большая причина для переключения (но может стоить того для тестирования причины - iterable + mocks - хороший способ проверить). redux-observable Я не вижу немедленной выгоды, если только наблюдаемые сами не принесут пользу, например, если вы хотите красиво дважды щелкать события.

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

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

Также актуально мое резюме, которое я придумал для шаблонов, используемых в gothinkster / react-redux-realworld-example-app.

Большинство людей, которых я знаю, которые активно используют redux, в конечном итоге отходят от redux-thunk, поскольку они обнаруживают, что он не очень хорошо масштабируется.

Я понимаю, о чем вы говорите, но вот моя обратная сторона: мы видим все больше и больше анекдотических свидетельств того, что огромная группа разработчиков JS еще даже не использует _arrow functions_ и другие базовые функции ES (6 | 2015). , из-за непонимания, запугивания и т. д. Ожидая людей, которые хотят начать работу с Redux и кому может быть полезно изучение _patterns_, которые вводит Redux, для первого изучения наблюдаемых или генераторов, я думаю, вероятно, слишком многого?

Redux-thunk также немного сложен в том смысле, что промежуточное ПО redux в целом искажает ваш мозг, но это, по крайней мере, просто функции / обратные вызовы, которые легко понять, если вы вообще пишете JS. Мне очень нравится идея иметь полный пакет связанных инструментов для начала работы, доступный через одну загрузку, даже если он представлен как «learn-redux» вместо «best-practice-always-redux». Подобно тому, как приложение create-response-app нуждается в настройке, когда вы изучаете все, что оно настроило для вас, это может стимулировать вашу собственную настройку, может быть, покажет, как преобразовать простую настройку redux-thunk для использования саг и т. Д. В качестве собственной формы "изгнания" ...

Просто мысли.

Я понимаю, о чем вы говорите, но вот моя обратная сторона: мы видим все больше и больше анекдотических свидетельств того, что огромная группа разработчиков JS еще даже не использует стрелочные функции и другие базовые функции ES (6 | 2015). , из-за непонимания, запугивания и т. д. Ожидая людей, которые хотят начать работу с Redux, и кому может быть полезно изучение шаблонов, которые вводит Redux, для первого изучения наблюдаемых или генераторов, я думаю, вероятно, требовать слишком многого?

Бинго! Мы находимся в среде, где МНОГО людей плохо знакомы с JS (или они «знают» JS, но это не их специальность, и они начинают с самого начала). Особенно, если эти люди являются опытными инженерами-программистами из другой экосистемы (java, rails и т. Д.), Они быстро попробуют применить известные им концепции, прежде чем изучать те, которые им не известны, и это не совсем сработает, и они застрянут. Я не знаю, как лучше всего убедить людей получить глубокое понимание JS, прежде чем переходить к функциональному шаблону проектирования UX.

Обратите внимание, что в документации Redux есть раздел о сокращении Boilerplate для тех из вас, кто читает что-то сейчас и не хочет внедрять всю библиотеку поверх Redux.

Мы должны быть немного осторожны с этим обсуждением и понимать, что это, вероятно, уже сильно разошлось. Команда Redux услышала, рассмотрела и отклонила множество вещей, которые, вероятно, будут здесь предложены. Вполне возможно, что из этого обсуждения ничего не выйдет, если мы будем спорить только о вещах, которые уже обсуждались.

При этом я думаю, что это отличная идея - поговорить о том, как сделать фреймворк более доступным для всех (новых и опытных).

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

Кривая обучения Redux может быть сложной, но как только вы поймете концепции, необходимость в
слои абстракции часто исчезают

Мне интересно, если это так, какие части Redux мы предлагаем улучшить? Какие части вы бы удалили или абстрагировались от того, что вам не нужно было бы немедленно добавлять обратно?

Это диаграмма всего жизненного цикла react / redux, которую я сделал для выступления на работе около года назад:
React Redux Lifecycle

У этого довольно много частей, но я не могу представить, чтобы Redux работал без какой-либо из них. Контейнеры иногда раздражают, но если вы удалите их, вы сильно увяжете логику представления с макетом данных. Если вы удалите действия, вы снова в основном будете MVC, в котором в первую очередь отсутствует смысл использования Redux. «Представление» на этой диаграмме уже почти не существует, потому что его можно смоделировать как просто функцию, которая подписывается на хранилище и визуализирует реагирующие компоненты.

Я не думаю, что нужно удалить много шаблонов в самой общей структуре. Возможно, вы имеете в виду шаблон в отдельных частях фреймворка, например, в создателях действий, редукторах или контейнерах. В этом случае советы со страницы « Уменьшение Boilerplate», упомянутой выше, уже касаются большинства из этих вещей. Нам не нужно ничего, чтобы сделать его «лучше». (Примечание: дело не в том, что я не готов добавить что-то, чтобы улучшить ситуацию, просто я этого еще не вижу.)

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

Уменьшение количества необходимых шагов (шаблон) не всегда решает проблему. Чтобы подчеркнуть мою мысль с самого начала моего поста, вы не хотите писать абстракцию, которая будет выброшена, потому что вы не думали обо всех способах ее использования людьми.

Хорошее обсуждение. Позвольте мне привести несколько быстрых примеров распространенных "шаблонных" жалоб, которые я вижу:

  • «Почему я должен писать функции« создателя действия »только для немедленного возврата объекта?»
  • «Мне нужно коснуться SOOO многих файлов только для того, чтобы добавить простую новую функцию! Кроме того, я постоянно повторяю одни и те же имена для констант, имен функций и ...»
  • «Зачем мне нужно это« промежуточное ПО »только для того, чтобы сделать вызов AJAX?»
  • «Почему я должен использовать операторы switch для всего?»
  • «Зачем мне эта штука dispatch ? Почему мне нужно свернуть все эти функции, чтобы они заработали?»

И несколько конкретных примеров таких комментариев:

И сразу же отбросить некоторые ответы на эти «шаблонные» проблемы: из этих пяти перечисленных категорий только «использование dispatch » на самом деле _required_. Что касается прочего:

  • Вам не _ нужно_ использовать создателей действий, но это хорошая практика для согласованности (согласно моему сообщению Idiomatic Redux: зачем использовать создатели действий? )
  • Вам не _необходимо_ иметь полностью отдельные файлы для создателей действий, констант действий и редукторов. Паттерн «утки» - это популярный подход для объединения всего этого в один файл. У этого есть обратная сторона - «сокрытие» возможности заставить несколько редукторов прослушивать одно действие. Redux в конечном итоге не заботится о вашей файловой структуре.
  • Вы _ можете_ полностью выполнять асинхронную работу вне Redux, как в компоненте. Но, согласно описанию Дэна в Зачем нам нужно промежуточное ПО для асинхронного потока в Redux? , обычно полезно извлекать эту логику за пределы компонентов, а промежуточное ПО обеспечивает «лазейку» для выполнения асинхронной работы при наличии доступа к хранилищу Redux.
  • Вы определенно _не_ должны использовать операторы switch в редукторах, это просто самый «очевидный» способ обработки нескольких значений для данной переменной. Таблицы подстановки, операторы if / else и все остальное, что вы хотите, вполне подойдут (согласно часто задаваемым вопросам: нужно ли мне использовать операторы переключения? )
  • Вам _do_ нужно вызвать store.dispatch() чтобы произошло что-нибудь полезное - это базовое дизайнерское решение Redux. Связывание создателей действий позволяет передавать их неподключенным дочерним компонентам и по-прежнему отправлять их при каждом вызове функции.

Так что в целом из этих "шаблонных" проблем почти ничего _required_. Это комбинация примеров из документации и «хороших практик программирования», таких как дедупликация кода и разделение задач.

Я думаю, что вопросы, поднятые @markerikson , действительно справедливы, и я сам задавал их в какой-то момент в прошлом.

Redux - это в некотором смысле «низкоуровневая» библиотека для моделирования данных. Как и любая такая низкоуровневая библиотека, она предоставляет множество вещей, от которых вы можете легко абстрагироваться, чтобы учесть большинство случаев. Я думаю, что причина, по которой @gaearon изначально не сделал этого, заключается в том, что он хотел сделать библиотеку как можно более маленькой и гибкой. Благодаря этому решению мы можем создавать множество разных вещей поверх Redux без необходимости иметь все в ядре Redux.

Может быть, нам следует подумать о том, что правильным путем может быть разработка и стабилизация хорошей библиотеки поверх Redux (например, Jumpstate?). Мы начинаем с обучения людей этому, а затем даем им простой способ использовать Redux напрямую, когда они в этом нуждаются.

Я не думаю, что Redux нужно намного больше в его основной кодовой базе, и я не вижу в ней какой-либо части, которую нужно было бы абстрагировать навсегда. (Если вы это сделаете, дайте мне знать: smile :) На мой взгляд, добавление или удаление чего-либо из ядра Redux не дает многого.

Улучшение библиотеки до такой степени, чтобы она была достаточно стабильной и гибкой, чтобы ее мог использовать каждый, вероятно, лучший вариант. Как вы сказали, на самом деле требуется не так много «шаблонов», поэтому давайте избавимся от них в библиотеке поверх Redux вместо того, чтобы изменять сам Redux.

Примером этого в другом сообществе является язык программирования Rust. Существует неблокирующая библиотека ввода-вывода для языка программирования Rust под названием «mio» . Он ориентирован на то, чтобы быть маленьким и низкоуровневым, как и Redux. Дело в том, что практически никто не использует его напрямую, потому что это было бы очень сложно и полно шаблонов. Практически каждый использует другую библиотеку под названием tokio, которая основана на mio и делает ее чрезвычайно удобной и эргономичной. Таким образом, любой, кому нужна сантехника от mio, может использовать ее напрямую, но любой, кто просто хочет что-то быстро сделать, может использовать tokio.

Мы должны принять аналогичную модель.

Чтобы расширить пару комментариев @sunjay :

В # 775 был недавний комментарий, который, как мне кажется, хорошо отражает ситуацию:

Redux - это общий фреймворк, который обеспечивает баланс между достаточной структурой и достаточной гибкостью. Таким образом, он предоставляет разработчикам платформу для создания настраиваемого управления состоянием для своих сценариев использования, при этом имея возможность повторно использовать такие вещи, как графический отладчик или промежуточное ПО.

Так что да, Redux во многих смыслах «просто образец». Ядро библиотеки действительно полнофункционально - единственными реальными частично запланированными изменениями являются такие вещи, как предлагаемая реструктуризация усилителя (# 1702, # 2214) и, возможно, повышение гибкости combineReducers (# 1768, # 1792 и т. Д.) ).

Прошло почти два года с момента создания Redux, и теперь у нас есть довольно хорошее представление о том, как люди его используют. В качестве одного из примеров @jimbolla собрала список всех известных средств разбила на категории, как они работают и для чего используются. Я по-прежнему остаюсь большим поклонником простоты и гибкости Redux, но мне бы хотелось увидеть поверх Redux некоторые все еще идиоматические абстракции, которые упростят общее использование и решат проблемы для людей.

Еще один набор полуфабрикатов , связанные с тем, и то , что у меня есть особый личный интерес, являются идеями «инкапсулированной логика / компонентов» (в @slorber «s „масштабируемый веб -

Интересно отметить, что @toranb проделал отличную работу по созданию оболочки Ember для Redux по адресу https://github.com/ember-redux/ember-redux . Мир Ember _ действительно_ находится в «соглашении по конфигурации», и поэтому ember-redux устанавливает разумную конфигурацию хранилища по умолчанию, включая redux-thunk и тому подобное. Такой подход может быть полезен.

Так что да, я как бы выкидываю здесь целую кучу разных мыслей, но они по-разному связаны. В целом, я хочу снизить барьеры для изучения и использования Redux и включить более сложные варианты использования по всем направлениям.

Redux - это общий, а не специализированный API. Это делает его более подробным и охватывает больше случаев. Его сила в сложном программном обеспечении, тогда как для любого нового или простого проекта это выходит за рамки необходимости.

Однако вы можете создавать специализации поверх общих API. Например, я использую https://github.com/acdlite/redux-actions, что уменьшает шаблон для общих случаев. Я до сих пор использую все возможности redux, и простого наличия этого интерфейса было бы недостаточно для моих нужд.

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

https://egghead.io/courses/getting-started-with-redux
https://egghead.io/series/building-react-applications-with-idiomatic-redux

Ссылка: Спектр абстракции: https://www.youtube.com/watch?v=mVVNJKv9esE

Как уже упоминалось, redux-actions неплохо удаляет некоторые шаблоны, удаление констант из уравнения путем присоединения .toString - действительно отличная идея, которая мне нравится, однако я предпочитаю писать эту логику самостоятельно, чем использовать redux-actions я сам, но это личный выбор для того, чтобы мой код был меньше.

Имхо, должен быть встроенный механизм (аргумент обратного вызова subscribe ?) Для наблюдения за потоком отправленных действий (я знаю, что это можно сделать в промежуточном программном обеспечении, но это довольно ограничивающий вариант использования, так как его нельзя использовать снаружи, т.е. по компонентам или connect )

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

  • Множество движущихся частей: хранилище, состояние, редукторы, создатели действий, действия, асинхронные действия, промежуточное ПО, подключенные компоненты.
  • Библиотеки. Для простого приложения, которое взаимодействует с REST API, вам понадобятся: redux, react-redux, redux-thunk (или другие) + дополнительные библиотеки, если вы хотите что-то протестировать.
  • Количество мест, в которые вы должны поместить код (см. _Движущиеся части_)

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

Как правило, я считаю, что множество движущихся частей вызывает разочарование.

Вот некоторые мысли, которые у меня были. Все это может быть построено на основе redux, чтобы оно оставалось таким, как есть.

  • Предоставьте библиотеку, такую ​​как response redux, которая дополнительно имеет встроенную поддержку асинхронных действий.
  • Многие асинхронные действия взаимодействуют с REST API, поэтому предоставьте идиоматическое промежуточное ПО для этого.
  • Пишите интеллектуальные компоненты как фактические компоненты вместо использования connect. Затем они могут отображать глупые компоненты в своем методе render
  • Назначьте масштабируемый макет файла для _container components_, _smart components_, _dumb components_, _action creators_ и _reducers_.
  • Предоставьте _redux-cli_ для генерации кода, например, redux action loadUsers
  • Стандартизируйте асинхронный уровень, такой как redux-saga или redux-observable, и включите его в документацию (было бы неплохо иметь _one_ место для консультации по большинству вопросов redux)
  • по умолчанию используются расширенные языковые функции (например, декораторы (@connect)) или TypeScript, чтобы сделать вещи менее подробными, в частности mapStateToProps и mapDispatchToProps (mobx требует декораторов, а синтаксис прост)

Т

Согласен, redux-actions - хороший пример некоторых простых абстракций, удаляющих шаблон.

Позвольте мне спросить: Create-React-App имеет пакет react-scripts , который имеет предварительно созданные конфигурации Babel и Webpack, и поставляется со встроенным набором разумных значений по умолчанию. Как может выглядеть соответствующий пакет redux-scripts ?

Я согласен с некоторыми другими (отрицательными) комментариями по поводу redux-thunk . Я бы не рекомендовал это новичкам (наверное, больше не рекомендую):

  1. Кажется, начинается волшебство.
  2. На самом деле это не так уж и много лишнего. Учитывая более сложный асинхронный процесс, необходимость получить dispatch из реквизита и передать его, оказывается, составляет лишь небольшую часть кода.
  3. Это приводит к созданию создателей действий, которые нельзя объединить в более крупные рабочие процессы.
  4. И последний момент, который я не могу четко сформулировать, превращая стиль redux в скорее фреймворк, чем библиотеку: вы полагаетесь на фреймворк для вызова своего кода, а не в библиотеку.

Мы довольно часто использовали его в приложении React-Native, и в основном он был полезен, но у нас были проблемы с составлением действий вместе (подумайте о «загрузке профиля после успешного входа в систему») из-за того, что создатели действий redux-thunk эффективно возвращают void (т.е. не имея ничего, кроме обещания использовать для упорядочивания следующего действия).

Это побуждает людей думать, что «единственный способ что-либо сделать - это немедленно dispatch из обработчика / обратного вызова React». А поскольку мы использовали connect из react-redux и сильно полагались на mapDispatchToProps , мы часто забывали, что наши обработчики событий могут быть просто функциями.

(обратите внимание, что приведенное выше приложение было в основном написано в начале прошлого года, и мы действительно не успевали за тем, что происходило в более крупной экосистеме Redux, поэтому оно может быть устаревшим).

@bodhi : не вдаваясь в подробности, я бы не согласился с некоторыми из этих выводов. redux-thunk состоит из 11 строк, и там есть несколько хороших объяснений, таких как "Что такое Thunk?" . Преобразователи _в некоторой__ степени компонуемы, и я думаю, что в целом проще сказать кому-то «напишите эти пару строк объявлений функций, затем сделайте свои вызовы AJAX и тому подобное здесь». У меня есть пост, в котором обсуждаются некоторые из различных компромиссов преобразователей (и в некоторой степени саг) в Idiomatic Redux: Мысли о преобразователях, сагах, абстракции и возможности повторного использования .

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

Я считаю, что использование redux-thunk означает не только выполнение чего-либо асинхронно, но и выполнение чего-то, что зависит от текущего состояния. Очень чистый, простой интерфейс и поощряет использование создателей действий.

Бодхи: Возможно, немного не по теме, но просто подумал, что, может быть, стоит упомянуть, что dispatch не возвращает void, он возвращает результат вашей внутренней функции. Так что если вы, например, вернете обещание, вы можете легко объединить действия в цепочку. См. Раздел о составе в readme:
https://github.com/gaearon/redux-thunk/blob/master/README.md

Помимо этого, я просто хотел бы поблагодарить сообщество за открытое обсуждение, очень интересно услышать все мысли и идеи.
Лично пока придерживаюсь thunks, но пытаясь четко отделить «что произошло» от «как должно измениться состояние». Я вижу довольно много случаев в нашем коде, где мы совершаем эту ошибку (используя действия, чтобы сообщить редукторам, что делать, вместо того, чтобы редукторы просто реагировали на то, что произошло), поэтому было бы неплохо увидеть некоторую библиотеку, которая каким-то образом усложнила эту задачу. делать (пока не продается в сагах).

19 марта 2017 года в 23:48 Bodhi [email protected] написал:

Я согласен с некоторыми другими (отрицательными) комментариями о redux-thunk. Я бы не рекомендовал это новичкам (наверное, больше не рекомендую):

Кажется, начинается волшебство.
На самом деле это не так уж и много лишнего. Учитывая более сложный асинхронный процесс, необходимость получать отправку от реквизита и передавать его, оказывается, составляет лишь небольшую часть кода.
Это приводит к созданию создателей действий, которые нельзя объединить в более крупные рабочие процессы.
И последний момент, который я не могу четко сформулировать, превращая стиль redux в скорее фреймворк, чем библиотеку: вы полагаетесь на фреймворк для вызова своего кода, а не в библиотеку.
Мы довольно часто использовали его в приложении React-Native, и в основном он был полезен, но у нас были проблемы с составлением действий вместе (подумайте о «загрузке профиля после успешного входа в систему») из-за того, что создатели действий redux-thunk эффективно возвращали void (т.е. ничего такого, как обещание использовать для упорядочивания следующего действия).

Это побуждает людей думать, что «единственный способ что-либо сделать - это немедленно выполнить отправку из обработчика / обратного вызова событий React». А поскольку мы использовали connect из react-redux и сильно полагались на mapDispatchToProps, мы часто забывали, что наши обработчики событий могут быть просто функциями.

(обратите внимание, что приведенное выше приложение было в основном написано в начале прошлого года, и мы действительно не успевали за тем, что происходило в более крупной экосистеме Redux, поэтому оно может быть устаревшим).

-
Вы получаете это, потому что подписаны на эту ветку.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите обсуждение.

(извините за продолжение касательной, но ...)

Стоит отметить, что отправка не возвращает void, она возвращает результат вашей внутренней функции.

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

Самое ценное, что сделало Redux намного проще для меня, - это рассматривать действия как события, а не команды . Это полностью избавляет от необходимости решать, как создавать действия и что в них вкладывать.

Компоненты не должны знать , как взаимодействие с пользователем должно влиять на состояние, они только сказать , что внешний мир случалась в них, например , «кнопка X нажата». Используя действия как команды, вы эффективно вводите двустороннюю привязку между компонентом и состоянием.

Редукторы не привязаны к компонентам, они представляют состояние приложения, а не состояние компонента , и они единственная сторона, которая действительно знает, как изменяется состояние. Нет когнитивного барьера при обработке одного действия в нескольких редукторах, потому что действие не является утверждением «что делать с состоянием» .

Это также устраняет необходимость синхронного выполнения нескольких действий.

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

Просматривая журнал действий в DevTools, вы можете увидеть полную историю того, что произошло внутри вашего приложения, и легко увидеть конкретный фрагмент состояния, на который повлияло действие. История остается самой короткой.

Этот подход, основанный на вытягивании, делает поток данных действительно односторонним и естественным redux-saga или redux-observable .

@aikoven, хотя я полностью согласен с этим (в прошлом определенно было много дискуссий по сравнению сокращения и поиска событий), что вы делаете с такими вещами, как FETCH_USER , которые очень часто встречаются (и что-то, что нужно сделать). Это кажется более «командным», чем «событийным».

@blocka Всегда есть какое-то событие, которое приводит к сетевому запросу. Сам запрос может быть заключен в действия FETCH_USER_STARTED и FETCH_USER_DONE / FETCH_USER_FAILED , так результат запроса попадает в состояние.

👍 для redux-actions

Что мне также нравится в этом, помимо простого сокращения шаблонов, так это то, что это просто кажется очень естественным продолжением redux. Для чего-то вроде jumpstate я чувствую, что реализация уходит немного дальше, и теперь мне придется выучить две вещи вместо одной.

Итак, я хочу сказать, что любые плагины, которые мы добавляем для уменьшения количества шаблонов, должны быть очень похожи на работу с redux, хотя и с менее подробным API.

Многие из шаблонов - это те же шаблоны, что и в любой среде. Когда вы сталкиваетесь с дублированием, мы обычно решаем его с помощью специальной абстракции. Эти абстракции очень часто бесполезны вне вашего текущего проекта, и «серебряной пули» просто не может быть. Требования к каждому проекту разные.

То же самое и с redux. Если вас устраивает, что вам нужно действие FETCH_X_STARTED , и создатель действия fetchX() , и редуктор для его обработки и т. Д., Не стесняйтесь создавать свою собственную абстракцию!

Обвинять redux в шаблоне - все равно что копировать и вставлять весь ваш код, а затем обвинять javascript в том, что у него слишком много шаблонов.

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

Использование redux-thunk для синхронного кода - не лучшая идея, и о нем следует упомянуть в документации.
Если вы объединяете много функций вместе, вы не уверены, что поток отправки не зависит от порядка, поэтому его сложнее обосновать и протестировать.

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

Я рекомендую этот пост в блоге, чтобы лучше понять: http://blog.isquaredsoftware.com/2017/01/idiomatic-redux-oughtts-on-thunks-sagas-abstraction-and-reusability/

@Machiaweliczny спасибо за статью. Думаю, вопрос ко мне больше о том, где вы в конечном итоге разместите свою бизнес-логику (как обсуждается в https://medium.com/@jeffbski/where -do-i-put-my-business-logic-in-a- React-redux-application-9253ef91ce1 # .3ce3hk7y0). Вы не говорите, что ваш поток отправки (thunk, epic, saga, что угодно) никогда не должен иметь доступа к текущему состоянию приложения, не так ли?

@dfbaskin

Имейте в виду, что Redux не является разработкой, ориентированной на предметную область. «Бизнес-логика» - это здесь очень расплывчатая проблема, и она больше «какая сигнатура функции концепции лучше всего соответствует логике, которую я пытаюсь реализовать». Ваша «бизнес-логика» распределена между селекторами, редукторами, создателями действий и «оркестраторами» (есть ли у нас более подходящее слово для этого?) В зависимости от того, что вам нужно.

Редуктор, будучи (state, action) => state - это то место, где обычно должна быть "логика, которая зависит от состояния". И, конечно же, в таких вещах, как Elm Architecture, вся такая логика находится в функции «обновления» (эквивалент нашего редуктора).

К сожалению, в Redux редуктор может обрабатывать только синхронную логику. Таким образом, асинхронная «бизнес-логика», которая зависит от состояния, должна либо получать ее из компонента через диспетчеризацию (если компонент имеет эту информацию, что не всегда), либо через вашу концепцию оркестратора по вашему выбору (thunk, sagas, epic), которые имеют для этого доступ к состоянию.

Если бы не ограничение редуктора, в этом не было бы необходимости. Вы действительно видите это, когда люди используют redux-saga или redux-observable: их действия / создатели действий обычно становятся почти тривиальными (в большинстве случаев плюс или минус некоторая нормализация или форматирование), а сага / эпопея - почти «альтернативные редукторы» , на этом теперь у вас есть еще одна вещь, которая имеет доступ к действию и состоянию и возвращает "вещь", и в результате фактическая сложность редуктора уменьшается. Редукторы и оркестраторы очень тесно связаны (иногда слишком тесно, и не очень хорошо иметь 2 конструкции, которые в половине случаев взаимозаменяемы ... но это то, что у нас есть, может также понравиться)

@Machiaweliczny : как автор этого поста "Мысли о Thunks", я могу заверить вас, что "избегайте использования thunks для синхронной работы" - это противоположность того, что я пытался сказать :)

Более хорошее обсуждение, но мы начинаем немного уходить от темы. (Это я вижу там навес для велосипедов? :))

Позвольте мне вернуться к исходным вопросам:

  • Как будет выглядеть идиоматическое использование Redux с «менее шаблонным»? Как мы можем решить эти жалобы?
  • Какие возможные абстракции можно было бы создать, чтобы упростить процесс обучения и использования, но без фактического сокрытия Redux (и, надеюсь, предоставит путь миграции / обучения к «базовому» Redux)?
  • Насколько из этого можно как-то решить улучшенную документацию?

Какие конкретные шаги мы можем предпринять для их решения?

Что касается бесспорных, действенных, краткосрочных шагов, я бы сказал:

1) Упростите настройку магазина (возможно, с конфигурацией по умолчанию? Я не знаю, так ли это до сих пор, но у Elm был тип «начального приложения» и тип обычного приложения. Использовалось стартовое приложение. для простых приложений и в учебных материалах, чтобы охватить 90% случаев, когда люди только учатся. Я признаю, что по сей день я не могу настроить хранилище Redux с помощью базового промежуточного программного обеспечения (devtools, thunks), не просматривая документ для подписей. Я не думаю, что многие люди будут спорить, что новичкам нужно знать, как настраивать промежуточное программное обеспечение магазина, чтобы изучать основные концепции Redux.

2) Это может быть уже так, убедитесь, что добавление Redux с указанным выше «стартовым магазином» в приложение create-response-app настолько просто, насколько это возможно, чтобы новичок мог запустить приложение Redux за 2 минуты.

Я думаю, это поможет нам очень и очень далеко.

Изменить: под начальным приложением я не имею в виду шаблон приложения, а скорее «createStore», который не может быть настроен, но имеет разумные значения по умолчанию, которые люди могут просто импортировать и делать с ним. Затем они могут просто перейти к «настоящему» createStore, когда они его перерастут.

Это звучит как довольно фантастическая концепция.

В понедельник, 20 марта 2017 г., в 10:02, Francois Ward [email protected]
написал:

Что касается бесспорных, действенных, краткосрочных шагов, я бы сказал:

1.

Упростите настройку магазина (возможно, со значением по умолчанию
конфигурация? Не знаю, так ли это до сих пор, но у Эльма раньше было
тип «начального приложения» и тип обычного приложения. Стартовое приложение использовалось для
простые приложения и учебные материалы, чтобы охватить 90% случаев, когда люди
только учится. По сей день я признаю, что не могу настроить магазин Redux
с базовым промежуточным программным обеспечением (devtools, thunks), не просматривая документацию для
подписи. Не думаю, что многие люди будут спорить, что новичкам нужно
чтобы знать, как настроить промежуточное ПО магазина, чтобы изучить ядро ​​Redux
концепции.
2.

Это может быть уже так, убедитесь, что добавляете Redux с указанным выше
"стартовый магазин" для создания-реагирования-приложения максимально прост, поэтому новичок
можно запустить приложение Redux за 2 минуты.

Я думаю, это поможет нам очень и очень далеко.

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287806663 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AFUmCQYkUwjkCugevDBWC8TOu0HhWJTnks5rnqMWgaJpZM4MhnVF
.

В наших модулях используется combineReducers так что каждый срез состояния в модуле имеет для него выделенный редуктор (я считаю, что этот подход изложен в разделе « Структурирование редукторов » документации, также известной как «редукторы срезов»). Это упрощает рассуждение, потому что операторы switch намного меньше. Это также позволило появиться в нашей кодовой базе распространенным редукторам. Простейшие редукторы были идентичны во всех модулях, за исключением их типов действий, поэтому мы смогли уменьшить шаблон, имея вспомогательные функции (фабрики редукторов?), Которые делают эти редукторы для нас по типу действия:

const { makeIndicator, makePayloadAssignor } from '../shared/reducers';

const searchModule = combineReducers({
  searching: makeIndicator(c.SEARCH),
  results: makePayloadAssignor(c.SEARCH_RESPONSE, [])
});

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

Это базовый рефакторинг javascript. Как я уже говорил ранее ... "javascript" имеет
много "шаблонов", пока вы не примените к своему коду такие вещи, как абстракция.

Redux - это просто javascript. В этом нет ничего волшебного.

В пн, 20 марта 2017 г., в 12:44, Маркус Кутзее [email protected]
написал:

В наших модулях используются combReducers, так что каждый сегмент состояния в
модуль имеет специальный редуктор для него (я считаю, что этот подход обрисован в общих чертах
в разделе " Структурирование редукторов" раздела "Документы",
редукторы "). Это упрощает рассуждение, потому что переключатель
заявлений намного меньше. Это также позволило появиться обычным редукторам.
по нашей кодовой базе. Простейшие редукторы были идентичны по модулям.
кроме типов действий, поэтому мы смогли сократить шаблон на
имея вспомогательные функции (фабрики редукторов?), которые делают эти редукторы для
нас по типу действия:

const {makeIndicator, makePayloadAssignor} из '../shared/reducers';
const searchModule = combReducers ({
поиск: makeIndicator (c.SEARCH),
результаты: makePayloadAssignor (c.SEARCH_RESPONSE, [])
});

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

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287820595 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AACourLpL5--NJiRzrWmKFJ31cl5DXJrks5rnqzxgaJpZM4MhnVF
.

Я согласен с большинством комментаторов, которые сказали, что лучше объяснить общие шаблоны редукции, чем разрабатывать какой-то шаблонный редуктор. Мои товарищи по команде и я начали работать с redux 1,5 года назад и в основном были сбиты с толку в самых простых вещах: что redux в основном является источником событий, что одно и то же действие может обрабатываться несколькими редукторами, это действие может содержать всю бизнес-сущность, а не только его идентификатор , что редукторы - это просто функции, и вы можете делать с ними все, что захотите - составлять, генерировать, разделять и т. д. Мы допускали типичные ошибки - использовали действия как удаленные команды и задавались вопросом, почему бы просто не использовать вызов классических методов; создавал огромные промежуточные программы и избегал саги о сокращении, потому что «генераторы слишком сложны» (хотя сага о сокращении превосходна!), создавал длинные файлы с огромными переключателями. Это, конечно, из-за посредственных навыков программирования, но также из-за отсутствия структурированной информации. Сегодняшняя документация намного лучше, спасибо разработчикам!

Это очень ценная тема для Redux как библиотеки.

Это базовый рефакторинг javascript. Как я уже говорил ранее ... "javascript" имеет
много "шаблонов", пока вы не примените к своему коду такие вещи, как абстракция.
Redux - это просто javascript. В этом нет ничего волшебного.

Отлично, @blocka! Я думаю, что это сообщение нужно распространять.

Redux кажется людям необычным и шаблонным из-за своего минимального подхода. Минимал кажется странным для «фреймворка» в целом (минимальный код, минимальные принципы).

Некоторые люди привыкли писать «каркасный» код, а не писать сам JavaScript. Когда разработчики используют фреймворк, неявно ожидаются встроенные способы действий. Чертовски грустно, но это правда.

Я считаю, что начать работу с Redux становится проще, чем когда-либо, но нам все еще нужно дать понять людям, что они не ждут, что Redux сделает все. @gaearon ясно говорит об этом все время, но, к сожалению, люди привыкли к тому, что фреймворки делают все. Почему у них должна быть мотивация изучать то, что «мало что дает»? Angular делает намного больше, чем Redux. Почему Redux? Ответ, наверное, очевиден для всех в этом выпуске. Но понятно ли новичкам?

Вчера я написал об этом небольшую статью: не вините в этом React или Redux . Конечно, я могу ошибаться во всем этом.

Есть прецедент, когда слои абстракции располагаются поверх расширенной библиотеки. Совсем недавно Tensorflow представил Keras в качестве абстракции поверх основного API: http://www.fast.ai/2017/01/03/keras/.

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

Я чувствую, что это похоже на большинство новичков, которые приходят в Redux. Замените Tensorflow на Redux и Keras на Jumpstate . Redux очень мощный, но большинству пользователей, вероятно, не нужен весь доступный контроль. Скорее всего, они пришли из Angular или их обучают React + Redux на буткемпе или из просмотра различных руководств. Хотя Redux не нужно заглушать для новых пользователей, он также не является анти-шаблоном, чтобы предоставить более простую абстракцию, которая, вероятно, может покрыть 80% потенциальных вариантов использования.

Да, если бы редукция была в порядке, мы бы не вели этого разговора. Независимо от того, является ли редукция полезным или структурно разумным, люди все равно чувствуют себя «плохо», когда впервые изучают его. Эти чувства действительны.

Люди, комментирующие в этой ветке, все являются экспертами по redux - конечно, мы довольны redux; мы усвоили его философию и чувствуем себя комфортно, создавая собственные абстракции для управления «шаблонным». Мы не являемся аудиторией, для обслуживания которой предназначена эта ветка. Нам нужно проявить сочувствие к пользователям, которые впервые переходят на redux, может быть, даже впервые приходят к функциональному программированию.

Например: вот жалоба, которую я часто слышу по поводу redux (которая, я не думаю, была упомянута upthread): недостаточно просто использовать redux, вам также «нужно» использовать response-redux, redux-thunk, redux-actions и т. Д. .

Вам буквально нужно использовать все эти другие пакеты для использования redux? Нет.
Будет ли большинство пользователей redux использовать некоторые или все эти дополнительные пакеты? да.

Имеет ли значение количество пакетов в package.json ? Нет, не совсем.
Влияет ли количество пакетов в package.json на самочувствие людей? Абсолютно.

Теперь я думаю, что справедливо полагать, что сам redux должен оставаться таким, какой он есть, и другой пакет ( create-redux-app или что-то еще) должен обрабатывать их вместе. Но у нас есть настоящая сложная проблема, и ее недостаточно, чтобы сообщить пользователям RTFM.

Независимо от того, является ли редукция полезным или структурно разумным, люди все равно чувствуют себя «плохо», когда впервые изучают его. Эти чувства действительны

Абсолютно. Но не все люди так думают. Некоторые делают. Имейте в виду, что вы никогда не услышите от людей, у которых не было проблем. Вы видите только тех, кто задает вам вопросы или нажимает stackoverflow / reactiflux. Из тех, кто никогда этого не делает, некоторым тоже нужна помощь, но они не знают, как ее попросить ... а у некоторых тоже все хорошо, и вы не хотите, чтобы им стало хуже ... иначе они будут вместо этого приходите на форумы, и это будет нулевой чистой прибылью.

Redux не стал популярным без причины. Чертовски много людей думали, что это чертовски хорошо, и рекомендовали это другим :)

Теперь, я думаю, справедливо полагать, что сам redux должен оставаться таким, какой он есть, а другой пакет (create-redux-app или что-то еще) должен обрабатывать их вместе.

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

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

Я не верю, что включение таких пакетов, как redux-thunk в ядро ​​Redux - это правильный путь.

Просто для ясности, идеи, которые я выкидываю, на самом деле не связаны с включением вещей непосредственно в ядро. Речь идет о гипотетическом создании некой «предварительно созданной конфигурации» или «уровня простоты использования», который мог бы быть отдельным пакетом, или инструментом CLI, или чем-то еще, более похожим на create-react-app .

Я полагаю, что мне лучше присоединиться как автор Jumpstate / Jumpsuit.

TL; DR:
Redux сложно изучить и сложно настроить / интегрировать, потому что он слишком низкоуровневый. Сообщество могло бы извлечь выгоду из стандартизированного высокоуровневого redux api, нацеленного на 90% -ный вариант использования, чтобы упростить кривую обучения и даже работать как решение для более простых проектов. Jumpstate пытается решить эту проблему, но это не долгосрочное решение. Нам нужно начать предлагать возможные идеи (реальный или метакод) о том, как может выглядеть этот api.


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

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

Я неизбежно попал в кривую обучения, и, обратившись за помощью, сразу понял, что маркетинговый и документированный подход для redux принял тон «Redux - это сложно, концепции низкоуровневые, api заблокирован, и вам просто нужно пройти через Это."

Вот что я делал вместе со всеми моими сверстниками. Мы прошли через это, потому что это было то, чему нас научили. Тем не менее, на этом пути я осмелился создать уровень абстракции на очень раннем этапе, который временно и намеренно скрывал некоторые сложные и расширенные функции, которые должен был предложить redux.

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

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

Мы разработали его таким образом, чтобы расширенное или «идиоматическое» сокращение можно было использовать, когда оно нам было нужно, но действительно разработали его для нашего случая использования 90%.

Я ни в коем случае не говорю, что jumpstate охватывает все основы, на самом деле есть еще ооочень много вещей, которые нужно изменить, чтобы jumpstate вел себя «идиоматически» (настраиваемые создатели действий, удаление глобального импорта действий ... их много) , но он определенно помог многим людям изучить основы и дал им возможность понять, как работает redux на очень простом уровне. Все время я получаю сообщение в Slack-организации Jumpstate о том, что jumpstate помог кому-то изучить redux.

Не имеет большого значения, используют ли эти люди сегодня jumpstate или нет (но многие люди все еще используют его в продакшене). Важен был их опыт и то, как быстро они смогли стать продуктивными в экосистеме redux.

Еще несколько идей, которые приходят в голову для этого обсуждения:

  • предложите мета-примеры того, как может выглядеть упрощенное сокращение, просто попробуйте!
  • обсудить требования и принять решение о стандарте для часто дублируемых и крайне самоуверенных промежуточных войн по сокращению. Мы могли бы начать с асинхронной обработки. Это могло бы решить такую ​​большую фрагментацию в сообществе redux и помочь всем усилиям изменить ситуацию к долгосрочному выживанию и использованию redux.

Насколько из этого можно как-то решить улучшенную документацию?

Много. Когда дело доходит до документации Redux, я чувствую, что она во многом хуже, чем документация AngularJS 1, потому что, как и AngularJS, она излишне многословна, но в отличие от AngularJS, она не соответствует принципу «показывай, не говори».

Документы Redux предпочитают фрагменты кода, а не фактическую демонстрацию кода, что означает слишком много моментов типа «вот набор кода; мы не будем рассказывать вам, как он соединяется, но поверьте нам, что он работает». Отсутствие возможности запускать примеры в браузере означает, что пользователь вынужден доверять своим инстинктам, что то, что они делают локально, работает, и если что-то не работает, они выключаются сами по себе. Я считаю, что даже простое приложение Todo List вряд ли является лучшим примером Redux "hello world" - его можно было бы сделать намного проще.

Диаграммы здесь, безусловно, помогут. Например, мне нравится @sunjay ; один, который может быть даже лучше, - это разработать его для самого примера списка Todo - как связаны файлы и т. д. с высокоуровневого представления. Изображения почти всегда лучше подходят для передачи длинного текста и могут помочь уменьшить многословие в документах. Изображения также помогут новичкам сосредоточиться и лучше понять Redux в целом.

Мои два цента: пожалуйста, не меняйте ядро. Его великолепие в простоте. На этом этапе добавление чего-либо, скорее всего, отнимет у целого.

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

Он может стоять сам по себе, пусть будет ❤️

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

@HenrikJoreteg , не бойся! Я почти уверен, что ничто из того, что мы здесь обсуждаем, никогда не изменит сути. Ядро полнофункционально и само по себе. :)

Много. Когда дело доходит до документации Redux, я чувствую, что она во многом хуже, чем документация AngularJS 1, потому что, как и AngularJS, она излишне многословна, но в отличие от AngularJS, она не соответствует принципу «показывай, не говори».

Это правда. Одна вещь, когда Redux был новым, - это то, что документов было мало, но основы были там. Многие приняли его, потому что это было «так просто». Но онлайн-ресурсы сейчас пытаются показать «методы реального мира», которые часто являются просто «моим любимым промежуточным программным обеспечением» и «моими любимыми стандартными инструментами сокращения». Люди ошеломлены.

Есть что сказать о "лучше меньше, да лучше"

@Phoenixmatrix , @Sylphony : а как будет выглядеть потенциальная переработка документации?

Лично, чтобы объединить это с моими вышеупомянутыми предложениями о создании «начального магазина», я бы разделил его на две части (не на 2 разных сайта / документа, а на 2 разных раздела).

«Архитектура Redux», которая будет иметь множество симпатичных простых рисунков, объясняет действия и редукторы, вводит react-redux и, возможно, thunks, использует «стартовый магазин» для ограничения любого вида предварительной конфигурации и показывает, насколько легко это можно сделать. быть для создания простого приложения, которое выполняет несколько запросов ajax и отображает данные на экране.

Все остальное можно найти в разделе «Исследование» с более продвинутыми концепциями. Даже тогда я бы, наверное, много чего выдрал. Кто-то сказал мне сегодня, что есть раздел о наличии нескольких магазинов в приложении. Это хорошо знать, но его применение действительно продвинуто. Не думаю, что новичку нужно наткнуться на это, не глядя.

Лучшая документация - это всегда отличная идея, но я не думаю, что это решает основную проблему. Библиотеки абстракций пишутся и принимаются из-за шаблонности и многословности API Redux. Те же самые библиотеки фрагментируют сообщество Redux, потому что они явно необходимы на том или ином уровне. Это расстраивает, когда тех же авторов, которые активно пытаются внести свой вклад в экосистему, публично выставляют и увольняют за то, что они «не понимают Redux». Если вместо этого сообщество сможет создать более простую абстракцию, не являющуюся частью ядра React, но в какой-то мере «благословенную», тогда все выиграют. Хардкорные пользователи продолжают использовать Redux как есть, другие люди могут использовать абстракцию с более простым / менее подробным API.

@derekperkins Как мы пришли к консенсусу по поводу «благословенной» библиотеки? Как мы решаем, что в нем входит и кто будет над этим работать?

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

Соответствующий xkcd: https://xkcd.com/927/

Да, ядро ​​redux и react-redux настолько близко к консенсусу, насколько это возможно. Даже redux-thunk и redux-actions довольно пограничны, потому что даже на этом уровне у большинства людей разные потребности.

Уменьшение шаблонов в Redux - это вопрос: "Мне не нужнотак что я отвлечусь от этого. Но даже для новичка «та часть» кардинально меняется.

Черт возьми, у нас работает много (несколько десятков) приложений redux, и сложно создать общий шаблонный стек сокращения, потому что разные приложения имеют разные требования. Это просто, когда у вас есть одно приложение или несколько с одинаковыми требованиями. Даже маленькие различаются совсем немного.

Идея здесь не в том, чтобы собрать инструментарий, который решает все проблемы для всех людей. Использование CRA в качестве примера: существует множество способов настроить Babel, Webpack и ESLint. CRA предлагает единый, самоуверенный способ заставить их всех работать без каких-либо проблем со стороны пользователя и сознательно выбирает ряд настроек, которые улучшают работу учащихся. Затем он позволяет пользователю управлять конфигурацией, _ если он хочет _.

Он также не пытается решить все варианты использования. CRA не пытается заниматься расширенным разделением кода, множественными точками входа, SSR или подобными вещами. Документы CRA _do_ указывают на другие инструменты и параметры, которые могут предлагать больше возможностей настройки и лучше работать в определенных случаях использования.

Это отличный способ выразиться. Что-то, чтобы быстро встать и бежать,
включает только установку redux и этот гипотетический слой конфигурации? Что
было бы круто.

Еще одна идея, которая у меня возникла, - это установить флаг в режиме разработки, который
наблюдайте за пользователями и открывайте для них возможности для дополнительного обучения. В
таким образом слой абстракции может служить интерактивным обучающим инструментом.
В пн, 20 марта 2017 г., в 16:14 Марк Эриксон [email protected]
написал:

Идея здесь не в том, чтобы собрать инструментарий, решающий все проблемы.
для всех людей. На примере CRA: есть масса способов настроить
Babel, Webpack и ESLint. CRA предлагает единственное, упрямое
способ заставить их работать без каких-либо проблем со стороны пользователя, и это
сознательно выбирает ряд настроек, которые улучшают работу
учащиеся. Затем он позволяет пользователю управлять конфигурацией, еслиони хотят .

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

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/reactjs/redux/issues/2295#issuecomment-287914805 или отключить звук
нить
https://github.com/notifications/unsubscribe-auth/AFUmCactFzsw7etmGGP8MFK6kfNaOzTJks5rnvorgaJpZM4MhnVF
.

@sunjay Я знал, что это за ссылка xkcd, даже не

Я согласен с @markerikson. Это не попытка учесть все крайние случаи для каждого человека. Это самоуверенное заявление основных разработчиков Redux: «Это хороший способ заставить все работать». Существуют нормальные значения по умолчанию, которые при необходимости можно изменить, но я готов поспорить, что значения по умолчанию будут работать для 80% разработчиков.

Это может быть или не быть написано на ядре Redux. Я все еще думаю, что есть место для чего-то вроде Jumpstate, которое делает больше, чем просто ускоряет процесс обучения.

Кривая обучения Redux может быть крутой, но как только вы поймете концепции, необходимость в слоях абстракции часто отпадает.

Я думаю, что до некоторой степени это правда, но не обязательно означает, что вы всегда хотите исключить уровень абстракции. Несмотря на то, что в прошлом я писал C и разбираюсь в распределении памяти, я предпочитаю писать на Go, где сборка мусора выполняется за меня. Согласно моему предыдущему примеру с Tensorflow, было бы более производительно писать в apis нижнего уровня, но также многое можно сказать о простоте использования абстракции Python keras. Точно так же для Redux vs Jumpstate (или любой другой абстракции, вытекающей из этой проблемы), шаблон не обязательно сложно написать, он просто громоздок для большинства случаев использования, которым не нужна вся гибкость исходного Redux.

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

  • Подмножество, удобное для Flow / TypeScript, которое легче набирать, чем ванильный Redux.
  • Не особо выделять константы (просто сделайте безопаснее использование строковых литералов).
  • Сохранение независимости от React или других библиотек представлений, но упрощение использования существующих привязок (например, предоставление реализаций mapStateToProps ).
  • Сохранение принципов Redux (сериализуемые действия, путешествия во времени и горячая перезагрузка должны работать, журнал действий должен иметь смысл).
  • Поддержка разделения кода более простым способом из коробки.
  • Поощрение объединения редукторов с селекторами и упрощение их совместного написания (подумайте о связках редуктор-селектор, которые легко писать и составлять).
  • Вместо того, чтобы объединять создателей действий с редукторами, полностью избавиться от создателей действий и сделать сопоставление действий-редукторов «многие-ко-многим» естественным (вместо того, чтобы уклоняться от этого, как это делают большинство библиотек).
  • Принятие разумных значений производительности по умолчанию, чтобы мемоизация с помощью Reselect «просто работала» для распространенных случаев использования, когда пользователи не писали этот код.
  • Содержит встроенные помощники для индексирования, нормализации, коллекций и оптимистичных обновлений.
  • Имея встроенную поддержку тестируемого асинхронного потока.

Разумеется, поверх ядра, хотя можно назвать его официальным Redux.
Кроме того, я не буду писать об этом. Но ты можешь.

Для меня несколько месяцев назад, когда я узнал redux , я прочитал документ, но не очень хорошо его понял, поэтому я трачу 2 дня, чтобы прочитать код src , а затем каждое описание о api из документ становится понятным .

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

Итак, я думаю, что чтение кода src - лучший шаг для изучения redux , и только после этого вы сможете более плавно понять и изучить среду redux .

поддержка async по умолчанию.

Я имею в виду, что нет необходимости использовать другой плагин, например redux-thunk, redux-saga .

поддержка async по умолчанию

Это так, просто люди смотрят на это 0,5 секунды, прежде чем искать что-то получше. Ничто не мешает вам вызывать API-интерфейсы внутри ваших компонентов, а затем вызывать отправку в разрешениях обратного вызова / обещания. Просто люди хотят сразу экстернализовать это (в том числе и я). Но вы можете отлично справиться с асинхронностью без какого-либо промежуточного программного обеспечения.

Комментарий @gaearon идеален, поскольку он подчеркивает, насколько широкое распространение. Я полностью люблю и ценю точность, элегантность и мощность Redux 2.0, которые он предлагает, и все же почти ни одно из этих улучшений не имеет для меня отношения!

Я на самом деле нахожу это увлекательным.

Моя собственная библиотека абстракций Redux делает почти противоположное. Я нахожу огромную ценность в действиях с одним редуктором, в объединении функций атомарного редуктора с их кодами действий и селекторами, в полном уничтожении строк в пользу объектных ключей. Это мое собственное 90% решение, больше похожее на CRA по отношению, чем на что-либо еще.

Интересный момент заключается в следующем: какие проблемы мы пытаемся решить? Есть много проблем с несколькими доступными пространствами решения. Если бы Дэн построил Redux 2.0 так, как он описал, я бы перестроил свою собственную библиотеку абстракций поверх этого!

@jbellsey Redux глобальном масштабе, но в определенной области - у вас может быть бесконечное количество экземпляров хранилища redux, но вы можете их комбинировать. В основном это полезно для библиотек. Если вы видите, что библиотека говорит о redux внутри, вы можете извлечь выгоду из ...

какие проблемы мы пытаемся решить?

Глобальное состояние приложения. R eliable В Е sthetics D elivered U nified е X tensible: сердце:

Никто не хочет глобалов. Но каждому нужен один: tm:

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

@markerikson Было бы неплохо создать документ / электронную таблицу, чтобы систематизировать эти мысли? Уже было несколько замечательных идей, и прошло всего 48 часов 🎉

По мне, я бы не рекомендовал людям использовать thunks или sagas. Вместо этого изучите методы внедрения зависимостей в JavaScript.

Redux становится проще, если я рассматриваю его как простую базу данных:

  • Я сообщаю Redux начальное состояние и то, как действие (событие) влияет на состояние приложения. (Как схема базы данных и хранимые процедуры.)
  • Затем Redux позаботится об управлении им и уведомлении слушателей, а также предоставляет способы проверки и отладки состояния.

Для меня это все, что Redux для меня (я бы не ожидал, что база данных сделает HTTP-вызов). Для ввода-вывода и асинхронных вещей я выполняю это вне Redux. Это делает мой магазин Redux предсказуемым. Подпись типа всегда store.dispatch(actionObject) . Никаких диспетчерских функций и никакого скрытого смысла внутри действия (например, отправка действия не вызовет API).

@tannerlinsley : Да,

Один недостаток для меня , начиная с этой дискуссии: У меня уже есть тонны материала , что мне нужно работать и писать. Большая часть этого налагается на меня, но это означает, что у меня недостаточно времени для работы над некоторыми темами, связанными с Redux, которые я хотел бы исследовать, не говоря уже о таких вещах, как серьезная переработка документации или создание нового набора инструментов из царапать.

Я абсолютно хочу участвовать в этих возможных усилиях, но для этого потребуются другие люди, которые должны присоединиться и работать вместе. (Знаменитые последние слова каждого сопровождающего OSS ... :))

Redux становится проще, если я рассматриваю его как простую базу данных

Это то, что я рекомендую!

  • Держите свой магазин в нормальном состоянии
  • Вы можете подготовить данные, например представления. Сделайте это с помощью специальных редукторов - тогда вам не понадобится reselect . Рассмотреть возможность.
  • Действия не должны запускать другие действия - это может показаться несложным. Но это сложно, если у вас есть крючки componentDidMount . Я не знаю, как это решить. Переместить это вверх по иерархии не всегда легко

FWIW, я использую Redux с D3.js (без React), и все идет хорошо. Некоторые примеры этого перечислены в d3-component .

Больше всего в привязках React Redux мне не хватает connect . Из приведенного выше плана / видения от @gaearon меня больше всего заинтересует "предоставление mapStateToProps реализаций".

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

Да, это похоже на то, что твиттер делает в своем магазине, по крайней мере, я так думаю - у них есть ветка entities которая содержит идентификаторы постоянных клиентов для карт данных и, например, timeline view, который в основном является основным фидом для вас. посмотрите, какие идентификаторы содержат ссылки на ветку сущностей, но уже предварительно вычислены.

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

@stefensuhat, когда я пытался реализовать Redux самостоятельно, я использовал цикл Promise, чтобы сделать возможными асинхронные действия. Вы можете проверить это на https://github.com/iddan/delux

@gaearon полностью согласен с вашим списком! Мы работали над шаблоном redux, следуя 90% списка в организации, с которой я работаю (также следуя принципам уток). На данный момент это ранний выпуск, еще не готовый к публикации.

Я определенно хотел бы внести свой вклад в эту хорошую идею!

@markerikson @tannerlinsley

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

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

Бремя претворения этих предложений в жизнь лежит на всех нас, кто интересуется каждой новой функцией или подходом. Хотя Марк начал обсуждение, я уверен, что никто не ожидает, что он все это реализует. :)

Да, список @gaearon идеален, но, как уже упоминали некоторые люди, это очень много. Любой, кто попытается взяться за это прямо, будет предан забвению. Я бы хотел, чтобы это произошло, несмотря ни на что, но я думаю, что меньшие части следует атаковать одновременно, а не строить полный слой поверх (снова подталкивая мой пример предварительно настроенного начального магазина;))

С учетом сказанного, когда / если кто-то пытается атаковать весь этот список, также имейте в виду, какие другие инструменты и фреймворки существуют за пределами Redux и даже за пределами React. React / Redux имеет интересный набор преимуществ по сравнению с vanilla Flux, MobX, VueJS и его экосистемой по сравнению с Angular. Что бы ни делало сообщество, оно, вероятно, захочет сосредоточиться на некоторых из этих преимуществ (некоторые из которых входят в список @gaearon ) и убедиться, что любой слой, созданный поверх, не становится полностью избыточным. Многие вещи, такие как отладка в путешествиях во времени, экосистемы промежуточного программного обеспечения и т. Д., Доступны в других местах.

Пример, который я придумываю: может возникнуть соблазн создать модуль, который позволит вам создать функцию, которая автоматически обновляет автоматически сгенерированный редуктор. Но как только вы это сделаете, вы скопируете MobX, так что делать это не очень полезно.

@Phoenixmatrix да, я имею в виду, что у redux есть промежуточное ПО по умолчанию, поэтому нам не нужно использовать внешнее. 😄

Я действительно не вижу ничего плохого в текущей реализации Redux. Boilerplate существует, но на самом деле это не имеет большого значения, если у вас есть система типов.

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

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

Когда был создан Redux, множество людей (включая меня) пытались создать эту штуку, и @gaearon получил лучшую реализацию и очень хорошо поработал над инструментами / демонстрацией. Первоначально он (а также Flux) получил большую популярность не только из-за путешествий во времени, но и потому, что эта концепция не нова для многих и сразу же кажется естественной.

Люди видят в Redux новую блестящую игрушку (что, в конечном итоге, оказывается не так просто на практике). Тем не менее, в Redux нет ничего нового, кроме того факта, что кто-то элегантно перенес эти концепции во внешний интерфейс. Шаблоны Redux и его экосистемы уже используются в распределенных системах, серверных приложениях с обработкой событийным источником, проектировании на основе предметной области, и люди, имеющие опыт работы с ними, очень легко поймут Redux.

К сожалению, люди хотят пропустить шаги и использовать Redux, ничего не зная о задействованных более общих шаблонах. Лично я рекомендую всем, кто хочет создать что-то серьезное в Redux, иметь минимальный опыт работы с распределенными системами. Это может показаться странным, но я думаю, что наличие такого опыта может дать вам очень серьезное преимущество прямо сейчас и в ближайшие годы.

Что именно мы создаем, когда создаем интерфейсное приложение?

  • Строим участника распределенной системы
  • Этот член содержит только подмножество данных более общей системы.
  • Этот участник имеет довольно ограниченные возможности (хранилище, пропускная способность, стабильность сети ...)

Итак, мы пытаемся построить что-то очень сложное. У нас есть ограничения, с которыми труднее справиться, чем с разработчиками баз данных, но мы хотим, чтобы все было проще, без повторного использования предыдущих знаний людей, которые действительно много лет думали об этих проблемах. Вам не кажется, что люди уже задумывались о том, как структурировать состояние внутри БД? как запросить это?

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

К сожалению, люди хотят пропустить шаги и использовать Redux, ничего не зная о задействованных более общих шаблонах.

Хорошо это или плохо, но Redux по сути выиграл битву за управление состоянием React. Это дает возможность формировать экосистему. Всегда найдутся разработчики, которым просто нужно что-то, что работает, и есть множество более простых приложений, где это все, что необходимо. Либо люди будут продолжать использовать другие уровни абстракции, либо их можно будет познакомить с правильными общими шаблонами с помощью простой библиотеки.

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

В этом суть проблемы. Redux as отлично работает для людей, которые его понимают. Однако упрощать это не обязательно плохо. Большинство людей больше не пишут ассемблерный код, хотя понимание этого обычно помогает писать лучший код. Просто большинство людей начинают не с этого.

Еще много хороших комментариев. Здесь есть масса идей, которые мы могли бы и должны изучить дальше.

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

Создайте новый пакет с названием, я не знаю, redux-starter или что-то в этом роде. Этот пакет может зависеть от redux-actions , redux-thunk и redux-logger и, возможно, от промежуточного программного обеспечения на основе обещаний. Он предоставит функцию с подписью function createReduxStore({reducers, middleware}) {} (на основе ранее сделанного комментария ). Может, даже не потрудитесь принять промежуточное ПО?

Функция createReduxStore() позаботится об обработке applyMiddleware и настройке горячей перезагрузки для корневого редуктора, а также о настройке расширения Redux DevTools. Если промежуточное ПО не предоставляется, оно будет настраивать включенные по умолчанию. Это может быть похоже на код настройки службы магазина в ember-redux или на функцию configureStore в моем примере приложения «Project Mini-Mek» .

Это, по крайней мере, минимизирует объем настройки, необходимой для начала работы, и предоставит скромный набор полезных функций.

Да, мне это нравится (ну, мне не нравятся redux-actions и промежуточное ПО на основе обещаний для новых пользователей, но я позволю вам повеселиться с байкшеддингом на этом). Не стал бы принимать промежуточное ПО, просто createStarterStore (reducer).

Возможно, даже замените combReducer, чтобы вы могли просто:

const store = createStarterStore({
   foo,
   bar,
   baz
});

где foo bar baz - редукторы.

Драт. Просто понял, что «библиотечная функция, которая устанавливает HMR для корневого редуктора», вероятно, не будет работать, потому что даже если мы позволим пользователю передать путь к своему корневому файлу редуктора, один или оба из module.hot.accept() API и require(path) шаг повторного импорта хотят использовать пути, которые можно статически анализировать во время сборки, а не переменные. (Я думаю ... Я могу ошибаться.) Ну ладно.

Но да, createStarterStore() может принимать либо корневой редуктор, либо объект срезов.

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

@slorber Я согласен с вами в этом

К сожалению, люди хотят пропустить шаги и использовать Redux, ничего не зная о задействованных более общих шаблонах.

Но не совсем об этом. Некоторые люди знают о шаблонах, задействованных в Redux, и именно поэтому они решили его использовать. Желание использовать что-то простое (или, по крайней мере, более простое) не обязательно означает, что пользователь не способен использовать более сложную реализацию. Это просто экономит время и силы.

Там, где я работаю, мы использовали Redux в течение года и обнаружили, что копируем / вставляем тот же код (только немного изменяя его), чтобы добавить новые ресурсы в магазин, поэтому в какой-то момент мы почувствовали необходимость реализации слоя поверх Redux, чтобы абстрагироваться от этого избыточного шаблона.
На мой взгляд, эта идея не только упрощает использование Redux, но и сокращает шаблон для наиболее распространенных частей (таким же образом react-redux сокращает шаблон при использовании Redux вместе с React).

Очень интересное обсуждение. Мои два цента как пользователя redux с самых ранних дней:

Вначале, насколько я помню, redux рассматривали скорее как протокол или набор разумных соглашений, чем как основу для создания приложений. Эта строгость является частью того, почему redux может быть ошеломляющим для новых людей и утомительным для масштабирования без использования собственных абстракций. Но простой способ, которым он преодолел беспорядок управления состоянием в 2015 году, также стал причиной его взлета, а минимализм позволил удивительным фреймворкам, таким как Apollo, совмещать работу, выполненную для разных проектов (особенно инструменты разработки), и давать знакомый способ. при необходимости «опускаться на более низкий уровень» в управлении государством.

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

С этой целью, возможно, текущий redux может стать таким пакетом, как redux-core , а сам redux повышает уровень абстракции, чтобы дать рекомендуемый способ создания приложений. Конечно, этому redux может быть любое количество альтернатив более высокого уровня (например, Apollo или что-то еще, использующее саги?) С использованием redux-core ...

Переформулируем вещи для пояснения и акцента:

Любая работа в рамках этого потока не будет включать серьезных изменений в существующей библиотеке Redux :) Обновление документации вполне возможно, и могут быть некоторые небольшие изменения, но существующий пакет redux останется как есть.

Что-нибудь вроде пакета redux-starter который я только что описал, или подхода «фреймворка», описанного Дэном, будет новым пакетом, который зависит от redux .

Я голосую за создание пакета, подобного предложению @markerikson . Когда у нас будет кодовая база, мы можем начать обдумывать api, фрагменты кода и другие подробные идеи. Тогда у нас будет место для создания проблем с конкретными функциями.

Вы можете использовать Delux в качестве стартера (jk)

Как постоянный пользователь Jumpstate от @tannerlinsley (а теперь один из сопровождающих) я невероятно рад этому. Мои причины использовать Jumpstate очень кратко изложены в исходном посте @gaearon . Сказав это, это не полное решение (никогда не предполагалось). Я думал о нескольких вещах, которые можно было бы добавить к этому только сегодня утром, а затем я обнаружил эту ветку и обнаружил, что вы, ребята, уже думаете об этом.

Многословный способ сказать: звучит потрясающе, я в деле, не уверен, сколько я могу внести (я постараюсь), но у вас, безусловно, есть чирлидер.

Я уже несколько раз использовал Jumpstate для обучения Redux и могу с уверенностью сказать, что это значительно сократило время обучения. Я думаю о Redux как о HTTP и о Jumpstate как о fetch. Я люблю Redux и написал с ним некоторые (до смешного) сложные вещи, но я также знаю, что 90% случаев более чем достаточно, чтобы научить большинству вещей.

Если подумать, это прекрасное место для отдыха. Одна из основных претензий к разработке внешнего интерфейса и JavaScript в целом - «отсутствие стандартных библиотек». Дело в том, что это (TM) , возможность разрабатывать полные приложения в браузере. Наконец, растет потребность в стандартных библиотеках. Вот где мы сейчас находимся.

Re: Кривая обучения, упрямство и абстракция:

Кажется, что Ajax - это область, в которой застревают новые ученики, независимо от того, учатся ли они использовать thunks, саги или эпики. Одна из областей, где у них, кажется, нет особых трудностей, - это создание действий - поскольку они просто старые объекты Javascript, и у нас есть дополнительная ясность, обеспечиваемая спецификацией стандартных действий Flux. Этот образ мышления привел меня к вопросу - почему бы не разработать стандартное действие Ajax для

Например

function fetchPosts(page) {
  return {
    type: 'FETCH_POSTS_REQUEST',
    // Ajax request setup
    ajax: {
      url: `/api/posts`,
      method: 'GET',
      data: { page },

      // Optional ajax meta attributes
      meta: {
        // Amount of time to debounce the execution of the request
        debounce: 400,
        // Amount of times to retry the request on failure
        retry: 2,
        // Amount of time before timing out
        timeout: 10000,  
        // The action type that cancels the request
        cancelType: 'CANCEL_FETCH_POSTS',
        // Strategy when multiple FETCH_POSTS_REQUESTs are in flight
        resolve: 'LATEST'
      }
    }
  };  
}

Действие ajax будет обрабатываться промежуточным программным обеспечением (которое будет реагировать на клавишу ajax в действии).

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

  • резкое уменьшение количества асинхронных действий, необходимых в вашем среднем приложении (поскольку асинхронные действия, связанные с ajax, отпадут)
  • легко понять, поскольку мы имеем дело только с простыми старыми объектами javascript
  • это декларативно, детали реализации не важны
  • различные реализации можно было менять местами без поломок
  • это идиоматический Redux (журнал действий по-прежнему имеет смысл, сериализуемый и т. д.)

Я слышу, как некоторые люди ссылаются на аргумент разделения проблем, но я бы сказал, что это естественное расширение того, что уже делают наши действия с запросом ajax. В настоящее время они настраивают действие с довольно ясным контекстом, 'FETCH_POSTS_REQUEST' , но со слишком маленьким контекстом, чтобы абстрагироваться от реализации запроса ajax. Не оставляя выбора, кроме как вручную выполнить запрос ajax в другом месте.

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

В заключение - кажется вполне возможным, что такая абстракция поможет упростить кривую обучения и количество кода, необходимого для написания общих приложений Redux. Есть ли у кого-нибудь какие-либо мысли по поводу этого подхода - какие-нибудь нарушения условий сделки, о которых вы можете подумать? @markerikson @gaearon

Уровень техники: redux-axios-middleware

В этой теме много чего происходит.

Что касается обсуждения сложности Redux. Лично я не согласен с тем, что люди жалуются на сложность и многословность Redux. Это компромисс, на который вы идете при использовании низкоуровневой библиотеки, основанной на архитектурах Flux & Elm. На домашней странице Redux сказано, что он вам может не понадобиться. Но у нас все еще есть люди, которые жалуются на то, что это сложно.

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

Я вижу проблему не в самом Redux, а в отсутствии прогрессивного, готового к работе способа его изучения. Как уже упоминалось, у React была такая же проблема, и решением была create-react-app .

Может быть, проблема даже не в этом, поскольку для этого есть отличные ресурсы (например, серия статей Дэна о яйцеголовых ). Возможно, проблема заключается в людях, которые хотят использовать библиотеку, которая решает сложные проблемы без какой-либо кривой обучения.

В любом случае, эта ветка не об этом.

@markerikson Я лично redux-starter .

_Хотя бы мне хотелось более крутое имя_: stuck_out_tongue:

Шаблон, необходимый для создания множества действий, - практически единственный недостаток, который я вижу у redux.

Это очень низкий уровень, но я думаю, что это здорово. Это одна из причин, по которой я предпочитаю, например, парадигму стиля Redux, а не MobX, хотя я понимаю ее полезность и буду использовать MobX. Но я был бы счастлив сделать это только сейчас, когда понимаю Redux. Поскольку Redux (или шаблон Redux в целом), данные не попадают «за кулисы». Как правило, везде, где код обрабатывается, вы его написали, а если нет, вы можете его понять (если вы нашли время, чтобы узнать, подробнее об этом позже).

Дело в том, что когда я впервые узнал о Redux, мне нужно было многое понять, но также и просто. Что-то может быть как сложным, так и простым. Однако из-за этого я подумал: «Ничего себе, эта концепция настолько логична! В ней так много смысла, я уверен, что смогу сделать это сам!» Итак, для моего первого проекта, вместо использования пакета Redux, я создал свой собственный небольшой магазин Redux.

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

Я думаю, дело в том, что, поскольку Redux настолько популярен, это, эээ, "навязчивость" может отвлечь новичков от того, насколько хорошо он работает в Javascript. Так что их менталитет может быть таким: «Хорошо, у меня есть React, Redux и т. Д., И т. Д., Теперь я стану замечательным программистом и сделаю отличное приложение!» Не то чтобы в этом что-то не так. Но они могут сосредоточиться на простом желании использовать новый блестящий инструмент для ускорения процесса разработки, не понимая, что заставляет этот инструмент работать.

Как только концепция будет понята, становится очень легко заставить Redux (или любой другой Redux-подобный шаблон) делать всевозможные вещи. Мне он нравится по той же причине, по которой мне нравится React по сравнению с другими (все еще отличными) инструментами, такими как Angular. _Это просто Javascript. _ Вот как работает Javascript!
Если бы необходимый шаблон можно было сократить с помощью какой-то парадигмы, это было бы здорово, но я думаю, что это небольшая цена, которую нужно заплатить за неограниченный dd powaaaaaa.

ИМО, все это «многословие - это компромисс» - всего лишь мазохизм; многословие не в службе ничего, это жертва вы делаете использовать Redux вообще. Я не виню Redux или javascript, я просто хочу отметить, что это несущественная сложность. Elm управляет всем, чего достигает Redux, с меньшим количеством строк и более простым кодом.

Итак, мы механически выписываем шаблон. Jumpstate и тому подобное облегчают жизнь, но есть ограничения на то, что вы можете делать во время выполнения, а с помощью машинописного текста / потока jumpstate не очень помогает. Но кодогенерация сложна, и никто не хочет добавлять что-то еще в свою и без того перегруженную систему сборки.

Если бы я мог иметь что-то вроде кода Elm, который был переведен на идиоматический Redux ... Будь по-прежнему моим бьющимся сердцем.

Вот некоторые из моих идей, надеюсь, я не повторю предыдущие комментарии:

Создатели действий могут использоваться как типы действий

actions.js

export function increase() {}

reducer.js

import { increase } from './actions.js';
export default handleActions({
    [increase]: (state) => state + 1
}, 0);

Поскольку функции имеют уникальные ссылки, мы можем рассматривать их как идентификаторы действий. Не совместим с FSA, но экономит много кода и предотвращает ошибки.

Действия могут быть отправлены асинхронно

async function a() {

}
async function b() {
}
store.dispatch(a());
store.dispatch(b()); // b() will be dispatched after a() resolves

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

redux === шаблон

https://github.com/Emilios1995/redux-create-module

но я думаю, что эта функция может полностью спасти вам жизнь.

Стоит различать два разных набора идей, обсуждаемых в этой цепочке:

  • фреймворк на основе redux с полным набором услуг
  • дополнительные функции в ядре redux

Я согласен с @markerikson, что ядро

Redux имеет довольно небольшую площадь поверхности API: createStore , applyMiddleware , combineReducers , bindActionCreators и compose . Но большинство из них - вспомогательные функции. Только createStore строго необходимо для работы Redux. Почему что-то из этого принадлежит ядру?

  • applyMiddleware создает упрощенный интерфейс для хранения усилителей. Но что более важно, applyMiddleware поддерживает _interface_ промежуточного слоя как стандартный способ добавления эффектов в хранилища redux. Экосистема промежуточного программного обеспечения возможна, потому что applyMiddleware имеет сравнительно простой интерфейс и позволяет пользователям запускать множество промежуточных программ одновременно.

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

  • bindActionCreators уменьшает часть шаблонов, связанных с диспетчеризацией действий. Но, наоборот, bindActionCreators также косвенно ответственен за репутацию Redux как шаблона. Это потому, что простое существование bindActionCreators поощряет использование создателей действий. Это особенно заметно при сравнении распространенности создателей действий (которые «одобрены» bindActionCreators ) и селекторов (которые задокументированы, но не имеют эквивалентной основной функции). Я видел много кодовых баз, использующих react-redux где mapStateToProps всегда является "заказным" селектором, но mapDispatchToProps всегда является картой объектов заранее написанных создателей действий.

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

  • Если промежуточное ПО представляет собой упрощение средств расширения хранилища, есть ли другие упрощения, которые могли бы быть широко полезными?
  • Какие другие формы композиции редуктора можно было бы реализовать вместо простой документации? Редукторные объекты ? Зависимые редукторы ? Линейная композиция ?
  • Может ли интеграция повторного выбора привести людей к созданию и составлению селекторов там, где они этого не делали раньше? Будет ли это чистым плюсом?

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

@modernserf : Во-первых, спасибо за ваши комментарии, а также за другие ваши недавние мысли о Redux. Все они чрезвычайно ценны и информативны, и, вероятно, их следует прочитать всем, кто участвует в этой теме. Итак, я свяжу их здесь:

Очень интересно, что вы должны поднять их, из-за вовлеченной истории (которую я только что потратил много времени на изучение своей статьи Дао Redux, Часть 1 - Реализация и намерение . В частности, redux-thunk был изначально был встроен прямо в Redux , и react-redux был выделен позже .

Вы правы в том, что эти утилиты действительно кодифицируют определенные шаблоны использования. Тем не менее, эти утилиты включены, потому что они кодифицируют _предполагаемые_ шаблоны использования: состав редукторов срезов, конвейер промежуточного программного обеспечения для асинхронного поведения и другого централизованного поведения, а также создателей связанных действий для упрощения процесса диспетчеризации действий из компонентов (особенно передачи функций между компонентами). к дочерним компонентам). В некоторой степени аналогично, хотя Reselect нет в ядре, Дэн явно поощрял его создание .

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

По вашим последним трем вопросам:

  • Я думаю, вы могли бы сказать, что промежуточное ПО - это «упрощение средств расширения хранилища», хотя я не думаю, что это справедливо для них. Скорее, это усилитель магазина для очень специализированной цели. Что касается другой работы, связанной с усилителями хранилища: Дэн сказал, что одна из основных частей ядра Redux, которые он все же хотел бы изменить, связана с тем, как инициализируются усилители. На самом деле существует два «конкурирующих» PR для изменения реализации усилителя магазина, которые остаются открытыми в течение очень долгого времени: версия @acdlite в # 1706 и версия @jimbolla в # 2214. Также интересно отметить, что Джим составил список всех известных средств улучшения магазина, чтобы помочь проанализировать, как сообщество на самом деле их использует. Я знаю, что предложение Джима было направлено на то, чтобы помочь авторам энхансеров упростить обычно наблюдаемое поведение. Итак, это направление, которое можно исследовать дальше.
  • Определенно существует множество других шаблонов для композиции и структуры редуктора. Я не совсем уверен, что мы могли бы сделать в отношении «зависимых» редукторов, поскольку это гораздо более нишевый вариант использования и, похоже, в значительной степени зависит от приложения. В связи с этим, в течение долгого времени Дэн закрывал все PR, которые предлагали добавить какой-то третий аргумент к combineReducers (а их было _ много_), но в конце концов позволил # 1768 продвинуться вперед на некоторое время. в то время как. Этот пиар также зашел в тупик.
  • Наиболее распространенным вариантом использования селекторов является прямое извлечение битов состояния и передача их в качестве именованных свойств. У нас также есть открытый PR для React-Redux за добавление сокращенного синтаксиса объекта для mapState , и мы получили множество запросов на это, хотя вы можете сделать то же самое с помощью Reselect createStructuredSelector .

Как я задокументировал в том посте "Tao of Redux", заявленные цели заключались в том, чтобы поддерживать API ядра Redux как можно меньше и поощрять экосистему поверх него . Кроме того, в начале разработки Redux Эндрю сделал комментарий о намерении «благословить» определенные плагины :

Как однажды сказал Гаарон (я не могу вспомнить, где ... возможно, Slack) мы стремимся быть похожими на библиотеки Koa of Flux. В конце концов, когда сообщество станет более зрелым, план состоит в том, чтобы поддерживать коллекцию «благословенных» плагинов и расширений, возможно, в рамках организации reduxjs GitHub.

Ранее я предлагал какую-то абстракционную библиотеку "простой установки Redux" или что-то в этом роде. Будет ли что-то подобное или хотя бы этот список "благословенных" дополнений достаточным в соответствии с вашими соображениями? (И вы, собственно, тоже сделали это в первом комментарии этой ветки.) Если нет, то какие-нибудь дополнительные предложения или идеи?

В конце концов, когда сообщество станет более зрелым, план состоит в том, чтобы поддерживать коллекцию «благословенных» плагинов и расширений, возможно, в рамках организации reduxjs GitHub.

Это то, что я бы тоже сделал, хотя, вероятно, пошел бы дальше: я бы реструктурировал проект в монорепозиторий, где текущий пакет redux становится чем-то вроде @redux/core , благословенно библиотеки, такие как Reselect и redux-action, переносятся в репозиторий и пространство имен, а сам пакет redux просто повторно экспортирует все эти пакеты в единое пространство имен.

Эта _sort of_ удовлетворяет ограничению не изменять ядро ​​redux. Кроме того, расширенная версия будет строгим надмножеством ядра и, следовательно, будет иметь обратную совместимость с ним. Новые функции будут исключительно добровольными и не будут иметь специального доступа к частному состоянию. Что касается «раздувания» - каждая из этих библиотек изначально мала, и они написаны таким образом, что их было бы тривиально встряхнуть.

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

Я думаю, это должно тебе кое-что сказать.

Предлагаемая мною структура monorepo - это в основном структура, используемая Lodash. Теперь - Lodash - интересная библиотека для моделирования: это огромный набор функций, многие из которых легко реализовать самостоятельно. Почти каждая функция в lodash могла бы быть более гибкой как «рецепт» - в конце концов, groupBy - это действительно _pattern_; кто мы такие, чтобы говорить, на каких структурах данных вы его используете?

И каждая функция lodash также доступна в своей собственной библиотеке _a la carte_. Нет _функциональной_ выгоды от import { groupBy } from "lodash" сверх import groupBy from "group-by" . Почему я должен иметь дело с тряской дерева, если я могу просто установить то, что мне нужно?

Но опыт использования Lodash в корне отличается от использования рецептов или нанобиблиотек. Вы знаете, что если вы что-то делаете с массивом и у вас возникает ощущение, что вы повторяете себя, вероятно, для этого есть функция Lodash. Вам не нужно искать рецепт, вам не нужно ничего устанавливать - скорее всего, вам даже не нужно добавлять в файл еще одну строку импорта. Он устраняет лишь малейшее трение, но наши дни наполнены такими моментами, и это складывается.

Надеюсь, вы не возражаете, если я добавлю свои 2 цента с другой точки зрения.

Школы мысли CQRS , Event Sourcing и, в конечном итоге, Domain Driven Design - великие предки, которые родили нам Flux и Redux . Хотя эти влияния иногда упоминаются , Redux и его дочерние инструменты заимствовали большую часть своей терминологии API из реализаций Flux и Flux, которые были популярны в то время. Это нормально, но я думаю, что мы упускаем некоторую возможность извлечь выгоду из существующих представлений разработчиков, которые могли иметь эти идеи.

Приведу два примера различий: в большинстве обсуждений, связанных с источником событий, которые я видел, действия Redux будут называться событиями . Redux ActionCreators будет называться командами . Я думаю, что эта терминология тоже дает некоторую дополнительную ясность и семантику. События - это регистрируемые сериализуемые данные. События описывают то, что произошло, в прошедшем времени. События можно воспроизвести. События не могут быть отменены. Команды имеют повелительный настрой. Команды запускают события .

Я подозреваю, что Event Sourcing как архитектурный паттерн наберет популярность в течение следующего десятилетия, и я думаю, что Redux может добиться некоторой юзабилити, ясности и простоты использования, если согласовать API и обсудить его с более широким сообществом.

Думаю, это обсуждение уже забито до смерти: https://github.com/reactjs/redux/issues/351

О, я не знал об этом, спасибо! : +1:

Похоже, что №351 был закрыт, потому что в то время не было никаких действий, которые можно было предпринять. Если мы находимся на этапе, когда мы пересматриваем решения API и язык, который мы используем, мне кажется, что сейчас подходящее время для того, чтобы возродить эту идею.

Я могу быть более конкретным.

Вот мое представление о том, как может выглядеть API, вдохновленный идиомами Event Sourcing :

Концепции

  • Наблюдаемый поток событий
  • Event Stream имеет хорошо типизированный набор поддерживаемых событий
  • Отправка команд в поток событий
  • Один или несколько клиентов используют поток событий

API

import { createEventStream, createProjection } from 'redux';

// Initialize the event stream separately from the store.  This becomes the one
// true source of truth for your application.
const eventStream = createEventStream({
  // Commands are the only thing that we want to couple to the eventStream.  The 
  // set of events which may end up in an eventStream should be easy to predict.
  //
  // A definition like this supports static analysis inference well for 
  // consumers that can leverage it.
  increment: () => ({ type: 'INCREMENT' }),
  decrement: () => ({ type: 'DECREMENT' }),
});

// Multiple stores with disjoint or overlapping data can be used to consume the 
// same event stream.
const store = createProjection(eventStream, reducer, init);
const adminStore = createProjection(eventStream, adminReducer, init);

// We don't need a jargon term ("Middleware"), or a dedicated hook to handle 
// async anymore.  We just register more subscribers to the eventStream.
eventStream.subscribe(myCustomMiddleWare);
eventStream.subscribe(sendEventsToAnalytics);
eventStream.subscribe(logEventsForPlayback);

// Calls to commands can be wrapped with React Providers or container components 
// in the same way that Redux currently does.  They can also be called directly.
eventStream.increment();

@ajhyndman : хотя я ценю предложение и обсуждение, этот велосипедный навес был полностью покрашен, и лошадь сбежала из сарая (чтобы полностью смешать метафоры). Дэн решил использовать терминологию Flux, а не термины CQRS / ES, и нет никаких планов по изменению основных API или терминов, используемых для концепций Redux.

(Кроме того, хотя у меня нет статистики, подтверждающей это, я предполагаю, что на данный момент больше людей, знакомых с использованием Redux «действий» и «создателей действий», чем с терминологией CQRS / ES, по крайней мере, в сообществе JS. )

У меня определенно сложилось впечатление, что этот разговор был раньше, и есть сильное желание не возобновлять его. 😄 Я не буду здесь давить слишком сильно. (Мне было бы интересно прочитать или продолжить этот разговор в другом месте, если есть лучшая точка соприкосновения.)

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

Я все еще утверждаю, что у сообществ Event Sourcing и Redux есть возможность учиться друг у друга.

  • Какие возможные абстракции можно было бы создать, чтобы упростить процесс обучения и использования, но без фактического сокрытия Redux (и, надеюсь, предоставит путь миграции / обучения к «базовому» Redux)?

Я думаю, что даже без заимствования терминологии и изменения API мы можем найти какие-то преимущества. Например, мне удалось познакомить людей с Redux , описав хранилище как «контейнер состояния, в котором currentState является« чистой функцией »(получено из или сокращено ) списка только для добавления (или потока) действий ».

Заглядывая в будущее, я думаю, что вполне возможно реализовать и абстрагироваться от серверной инфраструктуры, подобной redux (см. Apache Samza и некоторые другие работы группы инженеров LinkedIn). Если мы к этому стремимся, то должно быть возможно использовать аналогичные абстракции для управления состоянием клиента и сервера! Если мы можем этого добиться, почему бы не создать изоморфное постоянное хранилище Redux ?

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

Думаю, некоторые из этих идей меня только немного возбуждают! Надеюсь, вы простите мне слово свалка.

Боковое примечание: кажется возможным создать API-оболочку, подобную потоку событий, для Redux, которая реализует поверхность, которую я предложил выше!

https://github.com/ajhyndman/redux-event-stream

@ajhyndman Я думаю, что обертка - это правильный способ реализовать вашу идею 👍

В связи с упомянутыми вами инженерными работами samza и linkedin. Если другие не читали / не смотрели замечательную беседу « Переворачивание базы данных наизнанку с помощью Apache Samza», то, пожалуйста, найдите час, чтобы сделать это когда-нибудь! Думаю, в какой-то момент я видел, как Дэн упоминал об этом в ридми или твите. Этот доклад навсегда изменил представление о базах данных и управлении состоянием и является очень близким идеологическим родственником redux.

Это видео потрясающее! На самом деле это также второй пункт в списке благодарностей в README репозитория redux .

Привет всем!

Не будучи осведомлены о существовании этой нити, я разработал библиотеку , которая находится в пути прямой ответ на @markerikson «ы оригинальные вопросы и стуки от большинства вещей из @gaearon» s список .

Библиотека называется Kea :

screen shot 2017-08-06 at 13 10 03

Это абстракция от redux, redux-saga и повторного выбора. За исключением склеивания, соединяющего их вместе, Kea не претендует на создание чего-либо нового и по мере необходимости предоставляет необработанные создатели и редукторы действий redux, необработанные саги о сокращении и селекторы необработанного повторного выбора. Он не изобретает новой концепции.

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

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

Для меня эта библиотека всегда сильно сокращала шаблон, оставаясь верной самой сути redux.

В общем, хватит разговоров, вот код. Это пример того, что я называю «inline kea», когда логика напрямую связана с вашим компонентом. Этот режим отлично подходит, когда вы только начинаете, или в качестве альтернативы setState React.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { kea } from 'kea'

@kea({
  actions: () => ({
    increment: (amount) => ({ amount }),
    decrement: (amount) => ({ amount })
  }),

  reducers: ({ actions }) => ({
    counter: [0, PropTypes.number, {
      [actions.increment]: (state, payload) => state + payload.amount,
      [actions.decrement]: (state, payload) => state - payload.amount
    }]
  }),

  selectors: ({ selectors }) => ({
    doubleCounter: [
      () => [selectors.counter],
      (counter) => counter * 2,
      PropTypes.number
    ]
  })
})
export default class Counter extends Component {
  render () {
    const { counter, doubleCounter } = this.props
    const { increment, decrement } = this.actions

    return (
      <div className='kea-counter'>
        Count: {counter}<br />
        Doublecount: {doubleCounter}<br />
        <button onClick={() => increment(1)}>Increment</button>
        <button onClick={() => decrement(1)}>Decrement</button>
      </div>
    )
  }
}

Если ваше приложение растет и большему количеству мест требуется доступ к действиям increment и decrement или counter prop, вы можете просто разделить свой код следующим образом:

// counter-logic.js
import PropTypes from 'prop-types'
import { kea } from 'kea'

export default kea({
  actions: () => ({
    increment: (amount) => ({ amount }),
    decrement: (amount) => ({ amount })
  }),

  reducers: ({ actions }) => ({
    counter: [0, PropTypes.number, {
      [actions.increment]: (state, payload) => state + payload.amount,
      [actions.decrement]: (state, payload) => state - payload.amount
    }]
  }),

  selectors: ({ selectors }) => ({
    doubleCounter: [
      () => [selectors.counter],
      (counter) => counter * 2,
      PropTypes.number
    ]
  })
})
// index.js
import React, { Component } from 'react'
import { connect } from 'kea'

import counterLogic from './counter-logic'

@connect({
  actions: [
    counterLogic, [
      'increment',
      'decrement'
    ]
  ],
  props: [
    counterLogic, [
      'counter',
      'doubleCounter'
    ]
  ]
})
export default class Counter extends Component {
  render () {
    const { counter, doubleCounter } = this.props
    const { increment, decrement } = this.actions

    return (
      <div className='kea-counter'>
        Count: {counter}<br />
        Doublecount: {doubleCounter}<br />
        <button onClick={() => increment(1)}>Increment</button>
        <button onClick={() => decrement(1)}>Decrement</button>
      </div>
    )
  }
}

Пожалуйста, попробуйте и прочтите документацию, чтобы узнать больше о побочных эффектах с помощью redux-saga и других функциях, которые вы можете использовать.

Отзывы о Kea до сих пор были в подавляющем большинстве положительными, они цитируются из вопроса : «Большему количеству людей следует использовать KeaJS, чтобы сделать мир redux лучше! 👍» :)

Спасибо за ваше время и за то, что дочитали до этого места! :)

Выглядит хорошо! не очень нравятся волшебные строки, хотя 'increment'

Продвинулась ли эта дискуссия в другом месте? Является ли Кеа наиболее правильным из общепринятых исходов?

@lucfranken : нет, обсуждение

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

Бросаю шляпу на ринг здесь. Вот как я решаю эту проблему: https://github.com/HenrikJoreteg/redux-bundler

Я лично считаю, что это большое упрощение и сокращение шаблона.

Так я строил все, что строил в последнее время.

Думаю, это поможет:
https://github.com/anish000kumar/redux-box
image

Эй, в моей компании мы только что открыли исходный код библиотеки, которая управляет сетевым уровнем и удаляет много шаблонов из Redux. Это оказалось успешным для нас, но попробуйте сами: https://github.com/Brigad/redux-rest-easy/ (средняя статья: https://engineering.brigad.co/introduction-redux-rest-easy -6e9a91af4f59)

1_327nnvo3cuaqc-dsqpoq7w

вот мой подход к сокращению шаблона redux
image

https://github.com/zhDmitry/restate

Некоторое время назад я попросил в Twitter дать отзыв о том, что «шаблонный шаблон» означает для людей:

https://twitter.com/acemarke/status/969040835508604929

Возвращение Некро-Нити!

Согласно моей редакции первого комментария в этой ветке, обсуждаемые здесь идеи были превращены в наш пакет Redux-Starter-Kit . Пожалуйста, попробуйте его и посмотрите, насколько он может помочь вам упростить использование Redux!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги