Первый проект React завершен, расскажите о своих мыслях о хуках

React.js

предисловие

В этой статье не будетReactСодержание конкретных приложений является лишь некоторым дляhooksПо сравнению с предыдущим компонентом класса, дляhooksсобственное мышление.

Автор присоединился к текущей компании в августе этого года, из первоначальнойvueПеревести вReact. Поскольку у компании все еще есть несколько старых проектов, она не полностью инвестировала в раннюю стадию.Reactпроект находится в разработке. С октября я участвовал в процессе строительства нового проекта на уровне компании от 0 до 1, что также является моим первымReactпроект. мы полны объятийhooksДа, во время разработки этого проекта я также написал много кастомныхhooksметод, который включает в себя несколько общих функциональных компонентов, которые можно считать опытнымиReactконкретные приложения.

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

Разница между компонентами класса и компонентами функций

Обратите внимание,类组件а такжеhooks, эти две вещи на самом деле не являются одним и тем же понятием.hooksПросто набор инструментов для расширения функциональности функциональных компонентов. Настоящее сравнение должно быть类组件а также函数组件.

Давайте сначала посмотрим类组件а также函数组件разница.

Различия в написании кода

Это самое интуитивное отличие, код другой. Я случайным образом перечисляю несколько очень распространенных примеров, эти характеристики находятся в函数组件Нет в.

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

Различия в ментальных моделях

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

Функциональные компоненты фиксируют значения, используемые для рендеринга.

Приводим пример из статьи

function ProfilePage(props) {
  const showMessage = () => {
    alert('成功关注 ' + props.user);
  };

  const handleClick = () => {
    setTimeout(showMessage, 3000);
  };

  return (
    <button onClick={handleClick}>关注</button>
  );
}
class ProfilePage extends React.Component {
  showMessage = () => {
    alert('成功关注 ' + this.props.user);
  };

  handleClick = () => {
    setTimeout(this.showMessage, 3000);
  };

  render() {
    return <button onClick={this.handleClick}>关注</button>;
  }
}

мы используем类组件так же как函数组件Реализована та же логика. Оба компонента получатprops.userсвойство, мы нажимаем кнопку, через 3 секунды он будетalertСообщение об успешном переходе.

Если изначально было переданоpropsЗначение{ user: '帅wowo' }, затем нажимаем кнопку «следовать», в течение 3 секунд входящийpropsЗначение изменилось и стало{ user: '丑wowo' }. Эти два компонента будутalertЧто не так?

Студенты с опытом, безусловно, смогут легко ответить на него.

// 函数组件会打印
'成功关注 帅wowo'
// 类组件会打印
'成功关注 丑wowo'

Почему это так?(Обратите внимание, что этот пример аналогиченReactФреймворк не имеет ничего общего, простоjsОсновные функции, которые вы используете в любомjsможно воспроизвести в написанном коде)

существуетReactв компоненте класса ,propsХотя без изменений,ноthisвсегда переменный. Когда запускается асинхронное событие, оно получаетpropsилиstateВсегда в курсе. Конечно, у нас есть решение.

Например, мы можем переопределить данные, чтобы сохранить `props

handleClick = () => {
  const {user} = this.props;
  setTimeout(() => this.showMessage(user), 3000);
};

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

Или пишите события для функции рендераrenderсередина

class ProfilePage extends React.Component {
  render() {
    const props = this.props;

    const showMessage = () => {
      alert('成功关注 ' + props.user);
    };

    const handleClick = () => {
      setTimeout(showMessage, 3000);
    };

    return <button onClick={handleClick}>关注</button>;
  }
}

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

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

Почему мы используем функциональные компоненты + хуки

Многим может показаться, что это не нужно, они думают, что то, что официально выпущено, можно использовать как есть, и это очень легко написать, так зачем заморачиваться?

Что касается этого момента, я думаю, что самое важное — это изучить мышление больших парней, почему вы хотите сделатьhooksПриходить? Это определенно исправить некоторые проблемы в исходном процессе разработки.ReactИдеи команды на уровне дизайна могут в определенной степени отражать лучшие отраслевые практики в области проектирования фреймворков.

Далее я перечислю несколько, которые, по моему мнению,类组件несколько болевых точек. (Хорошее и плохое сравниваются, эти болевые точки сравниваются только с函数组件+hooks而言, технология постоянно развивается, и итерация технологии это нормальная тенденция)

1. Написание функциональных компонентов проще и гибче.

В функциональных компонентах нам не нужно наследоватьclassОбъектам не нужно запоминать эти жизненные циклы, не нужно определять данные в фиксированномstateсередина. Функции — это первоклассные граждане в js, а функциональное программирование позволяет нам более гибко организовывать код.

2. Компоненты класса имеют свои недостатки

Один на самом деле написан в разделе выше, если нам нужны данные, которые следуют только за представлением, мы не можем использовать их напрямую.propsилиstate.

Другой наиболее распространен, т.React, если мы определяем метод, мы должны использоватьbindИли стрелочная функция для ограничения этого методаthisобъем .

Хотя мы можем решить эти две проблемы, по сути, мы решаем их с помощью практики кодирования.类组件собственные недостатки.

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

3. Логика разбросана и ее трудно использовать повторно

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

Я возьму йогурт, чтобы поговорить оvue2а такжеvue3Изображение разницы в качестве примера

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

Мы видим, что логика фактически разбросана по компоненту класса, возьмемReactНапример, данные должны быть определены вstateЗатем вам нужно написать соответствующие методы событий, затем инициализировать логику в жизненном цикле, обработать при обновлении компонента и, наконец, записать в шаблонjsx.

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

И код таким образом,сложно повторно использовать, абстрагируя повторяющуюся логику, с которой мы столкнулисьmixin,HOC & render-props. Оба этих метода имеют самую большую проблему, т.propsИсточник недостаточно ясен.mixinНе говоря уже о том, что это все слезы, мы можем найти их только одну за другой.HOCПри многих уровнях вложенности может быть трудно определить источник, иHOCСтоимость обучения относительно высока, и это не очень удобно для новичков.(Эта часть отжата мной.vue2Используется для разработкиmixinа такжеHOCнаписано из моего опыта, т.к.Reactновичок и не сталкивалсяReactизmixinа такжеHOCЭто вне эпохи логики, так что если есть проблема с написанием, пожалуйста, укажите на это. Наконец, вздох,ReactиспользоватьHOCНо это так удобно!)

Но если мы используемhooks, я до сих пор использую одинvue3Объясняется схема составного API в Китае, после чего следует использованиеhooksРезультаты аналогичны.

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

Излишне говорить о повторном использовании логики, кто это сейчас?ReactВ проекте не так много настроекhooksкакие.

4.хуки больше соответствуют базовой концепции React

Философия дизайна ReactСтатья 1

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

Мы можем взять в качестве примера разницу в ментальных моделях, упомянутую ранее, где мы переходим вpropsпараметр{ user: '帅wowo' }, мы хотим, чтобы все события, связанные с этим параметром, сильно зависели от этих данных. это не должно быть похоже类组件Опять же, переданные параметры не соответствуют полученному результату.

Но функциональные компоненты могут это сделать, повторите приведенное выше предложение,Во время рендеринга компонентpropsа такжеstateне изменился.

Недостатки крючков.

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

1. Относительно большая умственная нагрузка

Также из-за приведенного выше предложения,Во время рендеринга компонентpropsа такжеstateне изменился. Эта особенность приводит к闭包陷阱Сейчас это одна из самых распространенных проблем в нашей разработке. Мы всегда должны обращать внимание на то,hooksДобавлены необходимые зависимости. При инкапсуляции некоторых компонентов с относительно сложными функциямиuseEffectУстранение проблем дублирования рендеринга иногда может быть сложным и непростым в отладке.

Эта функция函数组件Это также принесет много хлопот при выполнении оптимизации производительности, потому что каждый разpropsа такжеstateИзменения в данных вызовут函数组件Рендеринг всего в . нам нужно пройтиmemo,useMemo,useCallbackЭти методы вручную уменьшаютrender. Когда компонент имеет сложную структуру и много вложенных компонентов, также возникает головная боль при решении проблемы зависимостей. Конкретный контент по оптимизации производительности вы можете найти в моей предыдущей статье.

Обучение, которое эти точки приносят разработчикамhooksПо сравнению с стоимостью类组件будет больше.

2. Необходимость в более строгих спецификациях разработки

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

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

Поэтому разработчикам необходимо сформулировать конкретное техническое задание на разработку и строго соблюдать его при разработке.

компоненты класса 3.hooks и не могут полностью заменить

Хотя у нас многоhooksспособ улучшить函数组件функция. НапримерuseStateможет позволить函数组件Сохраняйте собственные данные. имеютuseEffectможет в какой-то степени компенсировать函数组件Недостатков жизненного цикла нет.

Уведомление:useEffectОн не предназначен для замены жизненного цикла, он просто предоставляет метод, подобный жизненному циклу. Эти два понятия по существу несопоставимы.

Чтобы узнать больше, вы можете прочитать этот блог Дэна,A Complete Guide to useEffect, это может помочь вам лучше понятьhooksсерединаuseEffect.

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

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

Итак, в течение определенного периода времени,hooksвсе еще будет следовать类组件сосуществовать.

Суммировать

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

спасибо, лайк

Спасибо, что прочитали. Если вы считаете, что эта статья была вам полезна, поставьте лайк и поддержите ее, спасибо.