fullstack-development / react-redux-starter-kit

Modular starter kit for React+Redux+React Router projects.
https://demo.fullstack-development.com/
MIT License
91 stars 13 forks source link

Отказаться от компонентов на классах. Перейти на функциональные компоненты с реакт хуками #147

Open sk1e opened 4 years ago

sk1e commented 4 years ago

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

По каким причинам мы не переходим?

in19farkt commented 4 years ago

Макс их боится 😂

in19farkt commented 4 years ago

А если серьезно, то там есть вопросы по поводу тестируемости хуков и компонент содержащих вызовы хуков. Если ты в эту тему уже копал, то поделись инфой, че там и как сейчас)

kinda-neat commented 4 years ago

https://paulgray.net/an-alternative-design-for-hooks/

in19farkt commented 4 years ago

Блэ, Макс)) ну все мы знаем что можно было сделать по другом и всё такое, но что сделано то сделано, не мы пилим реакт, повлиять на это мы тоже не можем, теперь остается только смириться и принять текущее апи хуков)

kinda-neat commented 4 years ago

ну вдруг Серега не знал :) и ща он узнает что можно было бы сделать лучше и текущая версия гомно, и не захочет использовать, а так чо, у меня особо пруфов/жестких предубеждений нет чтобы их не использовать или наоборот за то чтобы использовать, будем юзать - будем, нет - так нет) я не пишу так активно чтобы всеми этими вселенскими проблемами кидаться и жонглировать и ругаться что то гомно или это, просто держу в курсе и во всех кидаю этой статьей :)

chmnkh commented 4 years ago

А если серьезно, то там есть вопросы по поводу тестируемости хуков и компонент содержащих вызовы хуков. Если ты в эту тему уже копал, то поделись инфой, че там и как сейчас)

Там как минимум шеллоу рендер не работал, да.

in19farkt commented 4 years ago

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

kinda-neat commented 4 years ago

Звучит не круто

Znack commented 4 years ago

С хуками главная проблема — они не вписываются в общую концепцию языка своим API, которое ограничивает области применимости функций. Это их правило "не вызывайте в циклах и условиях" — яркий флаг того, как это жёскто не вписывается. По сути они переопределяют семантику языка, на котором React реализован, по мне — это ужасный пример API. К тому же их костыль "юзайте eslint правило, которое проверит, что у вас в корне только вызываются useState и подобные" не работает, когда мы используем функицональный подход (у меня на проекте была проблема, где в методе рендера в .fold() передаввались два коллбека на случай, если Option пустой или наполнен данными, понятно, что eslint это не словил).

sk1e commented 4 years ago

С хуками главная проблема — они не вписываются в общую концепцию языка своим API, которое ограничивает области применимости функций. Это их правило "не вызывайте в циклах и условиях" — яркий флаг того, как это жёскто не вписывается. По сути они переопределяют семантику языка, на котором React реализован, по мне — это ужасный пример API.

Не думаю что из-за ограничений на циклы и условия могут возникнуть проблемы. Если ты зашёл в цикл на рендере, значит ты хочешь отрендерить коллекцию компонентов. Хочешь хук в цикле - выноси компоненты из коллекций в отдельные и использую хук внутри. Также с условиями: ты рендеришь либо один компонент либо другой и также можешь всё это вынести и использовать хук внутри.

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

К тому же их костыль "юзайте eslint правило, которое проверит, что у вас в корне только вызываются useState и подобные" не работает, когда мы используем функицональный подход (у меня на проекте была проблема, где в методе рендера в .fold() передаввались два коллбека на случай, если Option пустой или наполнен данными, понятно, что eslint это не словил).

показывай пример)

sk1e commented 4 years ago

https://paulgray.net/an-alternative-design-for-hooks/

какая-то херь, если честно. Стрёмное и неудобное api:

const App = () =>
  ReactHook.Compose(
    useState(5),
    (_) => useEffect(() => ...),
    (_, [a]) => useState(2 + a),
    ([b, setB], _, [a, setA]) =>
      <div>
        {a}, <button onClick={() => setA(a + 1)}>+</button>
        {b}, <button onClick={() => setB(b + 1)}>+</button>
      </div>
  )
Znack commented 4 years ago

Не думаю что из-за ограничений на циклы и условия могут возникнуть проблемы. Если ты зашёл в цикл на рендере, значит ты хочешь отрендерить коллекцию компонентов. Хочешь хук в цикле - выноси компоненты из коллекций в отдельные и использую хук внутри. Также с условиями: ты рендеришь либо один компонент либо другой и также можешь всё это вынести и использовать хук внутри.

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

показывай пример)

render () {
  return maybeValue.fold(null, (val) => {
    const [state, change] = useState(); // вот такой кейс не словит линтер. 
    // ...
  })
}

Я понимаю, что тут разработчик сам ошибся и надо было выносить в отдельную компоненту, то что рендерится в случае, если в maybe лежит Just a. Но мы же для этого статические анализаторы и испльзуем, чтобы таких ошибок не бояться, а тут у нас простор для косяков вылазит. Обнаружить этот косяк кстати было не так просто в общем большом МР-е.

Znack commented 4 years ago

какая-то херь, если честно. Стрёмное и неудобное api:

Токсично и неконструктивно, Серег :) Давай по делу. Я не спорю, что там вербозное API, но оно хотя бы не идёт против общей концепции разработки на JS :)

sk1e commented 4 years ago

Токсично и неконструктивно, Серег :) Давай по делу. Я не спорю, что там вербозное API, но оно хотя бы не идёт против общей концепции разработки на JS :)

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

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

Znack commented 4 years ago

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

sk1e commented 4 years ago

Это не невероятный пример, это вполне реалистичная ситуация была

человек может не ознакомился с документацией? Почему он так написал? Лично для меня он невероятен.

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

https://reactjs.org/docs/hooks-intro.html#motivation

Для меня актульна первая проблема. Мы используем много HOC-ов на практике, а это неудобное API и в разы разрастающееся дерево реакт-компонентов. Производительность тоже не помешает.

Хуки - будущее, будущие либы будут предоставлять хуки и не будут предоставлять HOC-и. Чем раньше перейдём - тем лучше

Znack commented 4 years ago

человек может не ознакомился с документацией? Почему он так написал? Лично для меня он невероятен.

Блин, Серег, ты щас как типичный разработчик, который не понимает зачем нужны тесты и зачем нужна типизация. "Он что, не может запомнить, что у него функция такой-то тип принимает 25-ым параметром" аргумент вот такого уровня получился :) Опытный разработчик вполне может такие детали не заметить и пропустить. И все мы читали доку, я в том числе, это не помогает всегда помнить и держать в голве все нюансы.

будущие либы будут предоставлять хуки и не будут предоставлять HOC-и

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

in19farkt commented 4 years ago

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

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

Ну и хуки это не только замена HOC-ам, это возможность писать логику связанную с жизненным циклом компонент отдельно от них. Постоянно повторяющуюся логику можно вынести в хук и везде использовать, например, все мы в didUpdate ловили success какой-то коммуникации, легко выносится в хук и потом одной строчкой кода используется везде где нужно и не только с коммуникациями при желании.

in19farkt commented 4 years ago

Это не невероятный пример, это вполне реалистичная ситуация была.

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

Znack commented 4 years ago

Ну про эту "особенность" я упоминаю лишь как про симптом, меня разочаровывает весь React самой концепцией того, как API хуков был реализован. Сделать "stateful" функции — это второй симптом кстати :)

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

нет, это прямо далеко не первый :) То, что вы помните постоянно, где нельзя использовать хуки — это прекрасно, но у меня позиция другая. Я же отлично понимаю, что эта проблема решается просто увеличением когнитивной нагрузки. Я в целом про то, что решение влечет увеличение этой когнитивной нагрузки на ровном месте — просто чтобы чутка минималистичней API сделать пошли против концепции host-language (JavaScript). В JavaScript нет такой синтаксической единицы, которая бы позволила реализовать хуки, в итоге это было выдумано с помощью огромного stateful костыля под капотом и навязано для использования в своем коде.

sk1e commented 4 years ago

что эта проблема решается просто увеличением когнитивной нагрузки

и уменьшением когнитивной нагрузки от HOCов, которая, смею заметить, гораздо больше.

sk1e commented 4 years ago

"Он что, не может запомнить, что у него функция такой-то тип принимает 25-ым параметром" аргумент вот такого уровня получился :) Опытный разработчик вполне может такие детали не заметить и пропустить

Запоминаемость зависит от важности и частоты использования. У хуков этот показатель в обоих случаях высокий.

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

Safr commented 4 years ago

Хуки к сожалению или к счастью это будущее, они добавлены были, чтобы в дальнейшем перейти на Concurrent Mode в 17 версии, и классы станут deprecated. Concurrent Mode будет работать с функциональными компонентами. Что касается проблем с хуками, они постепенно будут решаться. Enzyme уже умеет в хуки. Но и само собой введение хуков облегчает бандл. React Router , React-Redux уже в последних версиях реализованы на хуках, стали быстрее (не проверял) и меньше весить. https://medium.com/@acesmndr/testing-react-functional-components-with-hooks-using-enzyme-f732124d320a