[Рекомендуется для трещин в стене] Говоря о крючках

React.js

Начиная с React16.8, Hooks API официально поддерживает React, и совсем недавно авторы Vue, особенно Рейн Брук, перевели и опубликовали статью в своем собственном«RFC API на основе функций Vue», и подчеркните в начале текста, что это самый важный RFC для Vue 3.0, и упомяните его в тексте

Функциональный API вдохновил React Hooks, предоставив новую схему логического мультиплексирования.

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

В следующей версии план был, React Vue не такой радикальный, React специально упоминается в документе

Удалять классы из React не планируется.

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

  • Совместимая версия: поддерживает как новый API, так и все опции версии 2.x;
  • Стандартная версия: поддерживает только новые API и некоторые опции версии 2.x.

Почему нам больше не нужен Class Component?

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

1. Поскольку в первую очередь существуют функциональные компоненты, почему вы ввели классовые компоненты?

Ранние компоненты React можно разделить на «состояние или нет».

// 无状态组件
const Welcome = (props) => <h1>Hello, {props.name}</h1>;

// 有状态组件
class Welcome extends React.Component {
    constructor(props) {
        super(props);
        this.state = {name: 'KuaiGou'};
    }
    
    render() {
        return <h1>Hello, {this.state.name}</h1>;
    }
}

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

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

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

2. Как хук сохраняет состояние компонента?

Это был первый вопрос, который у меня возник, когда я увидел Hook API. На самом деле в React это не проблема.Студенты, знакомые с React Fiber, должны знать, что состояние на самом деле сохраняется в атрибут memoizedState на Fiber, а не в this.state класса. Тогда проблема состояния решена.Если функциональный компонент также обращается к свойству memoizedState на волокне, эта проблема может быть решена.

в статьеУпомянуть

Помните, что в реализации хуков тоже нет «волшебства». Как отметил Джейми, это выглядит так:

let hooks = null;

export function useHook() {
    hooks.push(hookData);
}

function reactsInternalRenderAComponentMethod(component) {
    hooks = [];
    component();
    let hooksForThisComponent = hooks;
    hooks = null
}

Тем не менее, класс также может поддерживать хорошую бизнес-итерацию, в конце концов, мало стимулов для повторного изучения хуков?

3. Зачем нужны хуки?

В ответ на эту проблему в документации React упоминаются следующие три момента:

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

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

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

ответNO!

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

Так где именно вводится сложность? Одноклассники, знакомые с матрешками... Бах

Знакомьтесь с Ajax, обещание и другие асинхронные студенты API могут запомнить «обратный ад». Точно так же функции более высокого порядка, рендеринг, также, скорее всего, вызовет «вложенный ад», а с декораторами, а другие функциональные составные вложенности действительно круто ... Cool ... Было вложено

Но какой бы ад ни был однозначно плохой, давайте разберемся с последним вопросом.

Сложные компоненты становятся трудными для понимания

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

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

Действительно сложная связь между иерархией и иерархией, я позаимствую документацию React на пользовательских примерах, иллюстрирующих проблему Hook

import React, { useState, useEffect } from 'react';
// 通过friendID订阅好友状态
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

// FriendStatus获取好友状态
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

// FriendListItem获取好友状态
function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
};

компоненты более высокого порядка


function useFriendStatus(WrappedComponent) {
  return class extends React.Component {
    componentDidMount() {
        ChatAPI.subscribeToFriendStatus(
          this.props.friend.id,
          this.handleStatusChange
        );
    }
     
    componentDidUpdate(prevProps) {
        ChatAPI.unsubscribeFromFriendStatus(
          prevProps.friend.id,
          this.handleStatusChange
        );
        ChatAPI.subscribeToFriendStatus(
          this.props.friend.id,
          this.handleStatusChange
        );
      }

    componentWillUnmount() {
        ChatAPI.unsubscribeFromFriendStatus(
          this.props.friend.id,
          this.handleStatusChange
        );
    }
    
    render() {
      return <WrappedComponent isOnline={isOnline} />;
    }
  }
}

Следует отметить, что такие понятия, как высокоуровневые компоненты, по-прежнему имеют много характеристик и преимуществ.Хук не всемогущ, хук — это просто хук.

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

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

// async 
const P1 = new Promise(Something)
const P2 = new Promise(Something)

export default async function () {
  const res1 = await P1;
  //do Something
  const res2 = await P2;
  // ...
  return res2
}

// 以及 hook
function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);
  ...
  return isOnline ? 'Online' : 'Offline';
}

Напишите (закрепите) так много кодов, проще говоря, решение Hook - это проблема «вложенного ада», так как асинхронное решение «ада обратного вызова» то же самое. Они сделали различные оригинальные «размеры», код инкапсулирован в одно и то же измерение, чтобы достичьБолее интуитивно понятная и прозрачная передача «результатов расчета»цель.

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

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

就是函数本身啊! ! Что я должен делать? !

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

Почему здесь это не важно? Ответить на этот вопрос мне поможет функция Function-based, о которой пойдет речь ниже.

4. Продолжайте использовать API функций жизненного цикла на основе функций.

Vue прошел примерно тот же путь, что и React, на пути компонентизации, поэтому, когда кто-то спрашивает меня, в чем разница между Vue и React, я действительно не могу ответить из-за своего личного уровня 😂...

Возвращаясь к теме, все они прошли следующие этапы

  • Mixins
  • Компоненты высшего порядка
  • Renderless Components

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

Студентам, которые одновременно знают и хуки, и функции, не должно быть сложно найти огромную разницу между ними, и Vue, который имеет преимущество опоздавшего, также решает нерешенные проблемы хуков React (или React не думает). это проблема, и я не собираюсь ее решать. ), но я не хочу слишком много объяснять об использовании двух API, в конце концов, их документация очень хороша.

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

function useMouse() {
  const x = value(0)
  const y = value(0)
  const update = e => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

// 在组件中使用该函数
const Component = {
  setup() {
    const { x, y } = useMouse()
    // 与其它函数配合使用
    const { z } = useOtherLogic()
    return { x, y, z }
  },
  template: `<div>{{ x }} {{ y }} {{ z }}</div>`
}

Сравните пример версии React «Подписаться на статус друга» выше.

import React, { useState, useEffect } from 'react';
// 通过friendID订阅好友状态
function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}

Нетрудно заметить, что и хуки, и функции, основанные на функциях, делают только одно. Это просто попытка понять это,Логика завернута в функцию, что заставляет логику кода вести себя очень естественно.Я думаю, именно поэтому Youda, не колеблясь, отказался от варианта, существовавшего много лет во Vue, и напрямую заменил его на Function-based.

Потому что функции созданы для вычисления (состояния).

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

последние слова

, Подвела.

С таким количеством API я все еще не могу хорошо писать код.

использованная литература

насчет нас

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