Pull to refresh

Comments 27

Если речь идёт о современном мире, то react.js + mobx + react router как фундамент приложения, перекрывают абсолютно любую задачу, плюс mobx в отличие от древнего redux, дает нам возможность писать НАМНОГО меньше кода, плюс не нужны никакие хуки и this.setState() когда юзаешь mobx, плюс там оптимизирована производительность из коробки. Чистые функции в реальной жизни так и надо оставлять чистыми, а для всего остального есть классы с человеческим жизненным циклом. Когда вы пишите такие статьи, то люди для которых авторитетом является не свой разум, а статьи в интернете, просто берут их на вооружение, а потом рвут волосы на голове, потому что код становится не читаемым, все становится не очевидным и поддерживать это и развивать уже становится мучением, они просто увольняются и начинают проект с чистого листа, стараясь не повторять ошибок прошлого и начинают понемногу понимать, что думать то надо только своей головой, а не тем, что кто-то нацарапал в интернете. И спустя годы они становятся по настоящему разработчиками и читая очередную статью просто соглашается с ней или нет. Если в ней действительно что-то полезное для реальной жизни, тогда они берут это на вооружение, а не так как к сожалению большинство поступает, влом подумать, просто берут че написано и погнали. Так вот, мое мнение, что альтернатива которую вы предлагаете, это максимум для hello world, для всего остального это только абуза в будущем. По поводу программного редиректа для react router без дополнительных пакетов и танцев с бубном, продвинутые разработчики знают выход, если кому интересно пишите, поделюсь.

В списке маршрутов
//...
import { setHistory } from './helpers/redirect';

@withRouter
@observer
export default class Routes extends React.Component {
    render() {
        return <React.Fragment>
            <Route component={ HistorySetter } /> { /*  <-- Добавляем это */ }
            <Switch>
                { /* routes... */ }
            </Switch>
        </React.Fragment>;
    }
}

function HistorySetter({ history }) {
    setHistory(history); // <-- Прокидывем history в хэлпер
    return null;
}
//...

Код из `./helpers/redirect`
let history = null;

export function setHistory(h) {
    history = h;
}

export function helperRedirect(to) {
    history && history.push(to);
}

export function helperRedirectReplace(to) {
    history && history.replace(to);
}

Использование
import { helperRedirect } from 'helpers/redirect';

// в любом месте
helperRedirect('/login');
Согласен, а вообще я уже давным давно хочу написать свой роутер который как минимум лично для меня будет человеческим и максимально удобным, но лень меня одолевает)
react-router ну очень многого не умеет, тоже думаю о том, чтобы написать статью про проектирование качественного роутера. И про ssr на этом стеке тоже тема актуальная, хотя его, по моим прикидкам, сделать намного проще.
Печально что для SSR React ну очень медленно работает по сравнению с тем же jade(нынешний Pug), я замерял в том году производительность обоих, там разница как бездонная яма была в пользу jade(Pug) конечно))
Для сервиса шаблонизированных темплейтов на node.js я использовал Marko — он на порядок быстрее Pug, кстати, так как преобразует все в чистые функции. Выдерживал прессинг танка с коронными 4мс скоростью ответа (вход-выход по nginx). Возможно, пригодится

Реакт да, тормоз в этом смысле, но у него ssr это побочная фича, которая мало кому нужна
UFO just landed and posted this here
В статье были использованы материалы из статьи How React Hooks can replace React Router

Это называется перевод. Вольный, но перевод, с той же структурой, кодом и скриншотами. То есть это не вы автор, а Peter Ekene Eze. Давайте с уважением относиться к авторским текстам и не «рерайтить». У Хабра есть специальный тип статей для переводов.

Да, я знаю, но я не нашел как сделать метку «Перевод» под заголовком. Если подскажете исправлю и буду признателен.

UPD: исправился, при оформлении статьи не увидел сразу, что можно выбрать тип публикации «Перевод», прошу прощения у читателей, оформил в шапке ссылку на оригинал и указал автора.
Я так и не увидел пользы хуков (3 года на реакте). Давайте сделаем все чистым и функциональным, долой сайд эффекты! Ок. А теперь давайте добавим состояний в функции но будем считать что это функции! Эээ, а зачем? Как бы есть возможность писать компоненты и функциями и классами, зачем? Иного объяснения кроме как у Фейсбука есть немеряно легаси кода и есть подозрение что он в основном функциональный и теперь что бы его сильно не переписывать придумали вот такое а теперь пытаются продать комьюнити — у меня нет. С интересом выслушал бы иные мнения (мое подозрение основано на поведении Фейсбука в реализации graphQL — там такой же финт с продажей решения по n+1 problem)
Я читал доки, неоднократно. Если там есть есть ответ на мой вопрос — процитируйте его пожалуйста здесь. Повторное использование кода? Серьезно? Этого нельзя было сделать с классами? Мои соболезнования.
Ок, не будем далеко ходить и возьмем простой пример с конференции:
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);
  
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);
  
  return width;
}


import React from 'react';
import { useWindowWidth } from './utils/customHooks';

const Example = () => {
  const width = useWindowWidth();
  
  return (
    ...
  );
};


Покажите изящную альтернативу с классовыми компонентами. И это, на самом деле, довольно простой пример.

Еще примеры.
import useWindowWidth from 'bla bla';

@useWindowWidth
class MyAwesomeClassWithWhateverTheHellIsThis extends React.Component<IProps, IState>{
поехали...
}
Решение с хуками будет лучше тем, что:
1. Меньше кода. В случае с JS в данном примере это примерно в два раза меньше кода на реализацию useWindowWidth. Это без TS.

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

3. Когнитивная нагрузка ниже даже при использовании.
const Example: FC = () => {
  const windowWidth = useWindowWidth();

  return (
    ...
  );
}


@withWindowWidth
class Example extends React.Compоnent<WithWindowWidthProp> {
  render() {
    const { windowWidth } = this.props;

    return (
      ...
    );
  };
}

Чем больше компонент и больше хуков/декораторов, тем сильней разница.

4. Отсутствие лишних оберток, т.н. Wrapper-hell. Стоит хотя бы открыть React Developer Tools чтобы наглядно увидеть, что дает это преимущество.

5. Типизация HOC отдельный головняк.

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

У меня для тебя плохие новости, если ты реально находишь хуки полезными в реальной жизни, тем более когда давно уже существует MobX

Вы сами не находите свой комментарий деструктивным? Какие-либо аргументы подтверждающие бесполезность хуков будут?

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

По поводу MobX, он давно имеет официальное легковесное решение основанное на хуках.
Репозиторий: react-mobx-light
Оф. сайт: mobx-react.js.org

Вопрос такой, зачем хуки когда есть MobX? Самое минимально возможное количество кода + максимальная простота и понятность, это то, что дает MobX, а хуки это так, hello world для чистого реакта без всего остального, да, это слегка лучше setState, но как ни крути с ними кода больше, а когда бизнес логика компонента сложнее чем 2 + 2, то снежный код наростает и читаемость снижается сильнее чем просто чистая манипуляция с переменными(MobX подход)

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

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

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

Вопрос такой, зачем хуки когда есть MobX?

А какое отношение MobX имеет, например, к Context API, Refs API и жизненному циклу? Я не понимаю, почему вы противопоставляете MobX Hooks API, когда даже официальный адаптер его использует, команда MobX активно использует хуки, а сам Вестстрат читает по ним доклады на конференциях?

Ну решите задачу с помощью одного лишь Mobx:
const Foo = ({ handler }) => {
  const ref = useOnClickOutside(handler);

  return <div ref={ref}>Just click outside</div>;
};


это слегка лучше setState,

Хуки это не только useState. Последний, к слову, очень удобен во множестве кейсов.

а хуки это так, hello world для чистого реакта без всего остального

Nonsense

но как ни крути с ними кода больше,

Напишите короче:
const Foo = () => {
  const { isActive, setActive } = useState(false);

  const toggle = () => {
    setActive(s => !s);
  };

  return <button onClick={toggle}>Toggle Active</button>;
};

Код выше при необходимости переиспользовния сокращается до:
const Foo = () => {
  const [state, handler] = useToggle();

  return <button onClick={handler}>Toggle Active</button>;
};


то снежный код наростает и читаемость снижается сильнее чем просто чистая манипуляция с переменными(MobX подход)

Главная проблема ваших комментариев в этой теме, что вы, видимо, пытаетесь сказать, что подход MobX лучше и всем, и во всех кейсах надо использовать непременно его, причем складывается впечатление, что вам без разницы чему его противопоставлять. Я ничего не имею против MobX, мне нравится эта библиотека. Но со стороны ваши комментарии выглядят абсурдно. Особенно, когда вы аппелируете к авторитету, без использования каких-либо аргументов, просто поставив на место авторитета себя. О какой конструктивной дискуссии тут может идти речь? Не надо так.

И да, первая релизная версия «древнего» Redux, появилась с MobX примерно в одно и то же время.

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

Sign up to leave a comment.

Articles