Автор оригинала: David Wong.
В основном вводится использование использования состояния использования эффекта использования редуктора использования контекста
Вы все еще беспокоитесь о том, использовать ли функцию или класс? ——С крючками вам больше не нужно писать класс. Все ваши компоненты будут функциями.
Вы все еще пытаетесь понять, какую функцию крючка жизненного цикла использовать? ——С помощью крючков функцию крючка жизненного цикла можно оставить позади.
Вас все еще смущает этот момент в компоненте? ——Поскольку все классы потеряны, где еще это может быть? Впервые в твоей жизни тебе больше не нужно сталкиваться с этим лицом к лицу.
Самые простые крючки
Сначала давайте рассмотрим простой компонент с отслеживанием состояния:
изображение
Давайте взглянем на версию после использования крючков:
Неужели это намного проще! Как вы можете видеть, Пример становится функцией, но эта функция имеет свой собственный штат (округ), и она также может обновлять свой собственный штат (setcount) 。 Эта функция настолько потрясающая, потому что она вводит состояние использования крючка, которое является этим Крючок делает нашу функцию функцией с отслеживанием состояния 。
В дополнение к состоянию использования существует множество других крючков. Например, use effect предоставляет функцию, аналогичную componentdidmount, а use context предоставляет функцию контекста.
Крючки-это, по сути, особый вид функции, которая может вводить некоторые специальные функции в ваш функциональный компонент. Почему? Это звучит немного похоже на осужденных миксинов? Собираются ли миксины возродиться в react? Конечно нет. Мы поговорим об этой разнице позже. В общем, цель этих крючков-заставить вас прекратить писать классы и унифицировать функции.
Почему react строит крючки?
Слишком сложно повторно использовать компонент с отслеживанием состояния!
Мы все знаем, что основная идея react состоит в том, чтобы разделить страницу на множество независимых и повторно используемых компонентов и соединить эти компоненты в одностороннем потоке данных сверху вниз. Но если вы используете react в большом рабочем проекте, вы обнаружите, что многие компоненты react в вашем проекте на самом деле являются длительными и трудными для повторного использования. Особенно для компонентов, написанных как класс, они содержат состояние, поэтому повторное использование таких компонентов очень проблематично.
До этого, как правительство рекомендует решить эту проблему? Ответ таков: визуализируйте реквизит и компоненты более высокого порядка. Давайте взглянем на эти два режима.
Атрибут визуализации относится к использованию реквизита со значением функции для передачи узлов или компонентов, которые необходимо динамически визуализировать. Как показано в следующем коде, мы видим, что наш компонент поставщика данных содержит все коды, связанные со статусом, в то время как компонент cat может быть простым компонентом представления, так что dataProvider можно использовать отдельно повторно.
Хотя этот режим называется renderprops, это не означает, что вы должны использовать реквизит, называемый рендерингом. Обычно вы пишете это следующим образом:
Концепция компонента более высокого порядка лучше понята. Проще говоря, функция принимает компонент в качестве параметра и возвращает новый компонент после серии обработки. Посмотрите на следующий пример кода. Функция with user является компонентом высокого уровня. Он возвращает новый компонент, который выполняет функцию получения предоставленной им информации о пользователе.
Логика в функции крючка жизненного цикла слишком запутана!
Обычно мы хотим, чтобы функция выполняла только одну вещь, но наша функция крючка жизненного цикла обычно выполняет много вещей одновременно. Например, нам нужно инициировать Ajax-запрос в componentdidmount, чтобы получить данные, привязать мониторинг некоторых событий и так далее. В то же время иногда нам нужно сделать то же самое в componentdidupdate. По мере усложнения проекта код в этом блоке становится менее интуитивно понятным.
Занятия действительно сбивают с толку!
Когда мы используем класс для создания компонентов react, возникает также очень сложная вещь, то есть направление этого. Чтобы убедиться в правильности этого пункта, мы часто пишем такой код: это.. Щелчок по ручке. Привязать (этот) или такой код: < нажатие кнопки = {() = > это. Нажмите кнопку (E)} >. Как только мы забудем это связать, последуют всевозможные ошибки, что очень неприятно.
Есть еще одна вещь, которая меня беспокоит. Как я уже говорил в своей предыдущей серии react, пишите свои компоненты как можно более без состояния, потому что они более пригодны для повторного использования и могут быть протестированы независимо. Однако много раз мы используем функцию для написания простого и совершенного компонента без состояния. Позже, из-за изменения требований, этот компонент должен иметь свое собственное состояние, и нам приходится с большими проблемами менять функцию на класс.
В этом контексте родился хукс!
Что такое государственные крючки?
Вернемся к примеру, который мы использовали в начале, давайте разберем его, чтобы посмотреть, что сделали крючки состояния:
Объявите переменную состояния
Use state-это функция-крючок react, которая используется для объявления переменных состояния. Полученный нами параметр estate-это наше начальное состояние, которое возвращает массив. Элемент [0] этого массива-значение текущего состояния, а элемент [1] – функция метода, которая может изменять значение состояния.
Итак, что мы делаем, это объявляем переменную состояния count, устанавливаем ее начальное значение равным 0 и предоставляем функцию setcount, которая может изменять количество.
Приведенное выше выражение заимствует разрушение массива ES6, что может сделать наш код более лаконичным. Если вы не знаете, как использовать этот метод, пожалуйста, сначала прочтите мою статью: освоите основное содержание ES6/es2015 за 30 минут (I).
Если вам не нужна деконструкция массива, вы можете написать ее следующим образом. На самом деле, деконструкция массива-очень дорогая вещь. Используя следующий метод записи или вместо этого используя деконструкцию объекта, производительность будет значительно улучшена. Для получения более подробной информации перейдите к анализу этой статьи: уничтожение массива для возврата нескольких значений (в свете крючков react). Если мы не будем подробно раскрывать его здесь, мы будем использовать деконструкцию массива в соответствии с официальной рекомендацией.
Считывание значения статуса
Это очень просто? Поскольку наш счетчик состояний является простой переменной, нам не нужно писать {это. Государство. Считай} больше.
Состояние обновления
Когда пользователь нажимает кнопку, мы вызываем функцию setcount, которая принимает измененное значение нового состояния в качестве параметра. Следующее, что останется сделать, это отреагировать, что приведет к повторному отображению нашего примера компонента и использованию обновленного состояния, а именно. Давайте остановимся и подумаем об этом. Пример, по сути, является обычной функцией. Почему он может помнить предыдущее состояние?
Почему хук запоминает состояние, а не каждую инициализацию?
Здесь мы обнаруживаем проблему. Вообще говоря, переменные, которые мы объявляем в функции, уничтожаются после запуска функции (здесь мы не рассматриваем сначала замыкания и другие ситуации). Например, рассмотрим следующий пример:
Независимо от того, сколько раз мы повторно вызываем функцию add, результат будет равен 1. Потому что каждый раз, когда мы вызываем add, переменная результата начинается с начального значения 0. Почему приведенная выше функция примера принимает последнее выполненное значение состояния в качестве начального значения каждый раз, когда она выполняется? Ответ таков: реакция помогает нам запоминать. Что касается механизма реакции , оставьте неизвестность.
Что делать, если компонент имеет несколько значений состояния?
Прежде всего, состояние использования может быть вызвано несколько раз, поэтому мы можем написать следующее:
Во-вторых, начальное значение, полученное штатом США, не предусматривает, что оно должно быть простым типом данных, таким как строка/число/логическое значение, Он может принимать объекты или массивы в качестве параметров 。 Единственное, что нужно заметить, это то, что перед Что делает наш this.setstate, это возвращает новое состояние после слияния состояния, в то время как usestate возвращает новое состояние после прямой замены старого состояния 。 Наконец, react также предоставляет нам редуктор использования, если вы предпочитаете схему управления недвижимостью в стиле Redux.
Из примера с функцией многих состояний мы можем видеть, что состояния использования независимы друг от друга независимо от того, сколько раз они вызываются. Это очень важно. Почему ты так говоришь?
На самом деле, когда мы смотрим на “форму” хука, она немного похожа на миксины, которые ранее официально отрицались. Все они обеспечивают возможность “внедрения подключаемых функций”. Причина, по которой миксины запрещены, заключается в том, что механизм смешивания позволяет нескольким миксинам совместно использовать пространство данных объекта, поэтому трудно гарантировать, что состояния разных миксинов, от которых они зависят, не конфликтуют.
Теперь наш крючок, с одной стороны, напрямую используется в функции, а не в классе; с другой стороны, каждый крючок независим друг от друга, и разные компоненты, вызывающие один и тот же крючок, также могут обеспечить независимость своих соответствующих состояний. В этом и заключается существенное различие между ними.
Как реагировать на то, чтобы состояния многократного использования были независимы друг от друга?
В примере со многими состояниями, приведенном выше, мы трижды вызываем состояние использования. Каждый раз, когда мы передаем параметр, это просто значение (например, 42, “Банан”), Мы не сказали react, какому ключу соответствуют эти значения. Каким образом react гарантирует, что три состояния использования найдут свое соответствующее состояние?
Ответ заключается в том, что react основан на порядке, в котором отображаются состояния использования. Давайте посмотрим подробнее:
Если мы изменим код:
таким образом,
В связи с этим Act предусматривает, что мы должны записывать хуки на самом внешнем уровне функции, а не в операторах условий, таких как ifelse, чтобы гарантировать согласованность порядка выполнения хуков 。
Что такое крючки эффекта?
Давайте добавим новую функцию к примеру в предыдущем разделе:
Давайте проведем сравнительный анализ. Если бы не было крючков, что бы мы написали?
Компоненты с отслеживанием состояния, которые мы пишем, обычно имеют множество побочных эффектов, таких как инициирование Ajax-запроса для получения данных, добавление регистрации прослушивания и снятие с регистрации, изменение DOM вручную и т.д. Ранее мы описали функции этих побочных эффектов в функциях жизненного цикла, таких как componentdidmount, componentdidupdate и componentwillunmount. Теперь use effect-это набор крючков, которые объявляют периодические функции. Это один на троих.
В то же время крючки можно использовать многократно и независимо. Таким образом, ваш разумный подход состоит в том, чтобы дать каждому побочному эффекту отдельный крючок эффекта использования. В результате эти побочные эффекты больше не накапливаются в крючках жизненного цикла, и код становится более понятным.
Что делает эффект использования?
Давайте рассмотрим логику следующего кода:
Сначала мы объявляем переменную состояния, подсчитываем и устанавливаем ее начальное значение равным 0. Затем мы сообщаем react, что у нашего компонента есть побочный эффект. Мы передали анонимную функцию useeffecthok, которая является нашим побочным эффектом. В этом случае наш побочный эффект заключается в вызове API браузера для изменения заголовка документа. Когда react визуализирует наши компоненты, он запоминает побочные эффекты, которые мы используем. После повторного обновления DOM он, в свою очередь, выполняет функции побочных эффектов, которые мы определили.
Вот некоторые моменты, которые следует отметить:
Во-первых, react вызывает функцию, переданную для использования эффекта один раз для первого рендеринга и каждого последующего рендеринга. Ранее мы использовали две объявленные периодические функции для представления первого рендеринга (componentdidmount) и повторного рендеринга (componentdidupdate), вызванного последующими обновлениями.
Во-вторых, выполнение функций побочных эффектов, определенных в useeffect, не помешает браузеру обновлять представление, то есть эти функции выполняются асинхронно, в то время как предыдущий код в componentdidmount или componentdidupdate выполняется синхронно. Такое расположение является разумным для большинства побочных эффектов, за исключением некоторых случаев. Например, иногда нам нужно рассчитать размер элемента в соответствии с DOM, а затем повторно отобразить его. В это время мы надеемся, что повторный рендеринг будет происходить синхронно, то есть это произойдет до того, как браузер фактически нарисует страницу.
Как избавиться от некоторых побочных эффектов эффекта использования
Этот сценарий очень распространен. Когда мы добавляем регистрацию в componentdidmount, нам нужно немедленно очистить регистрацию, которую мы добавили в componentwillunmount, то есть до того, как компонент будет отменен, или возникнет проблема с утечкой памяти.
Как его очистить? Давайте вернем новую функцию в функцию побочного эффекта эффекта использования. Эта новая функция будет выполнена после следующего повторного рендеринга компонента. Этот шаблон распространен в реализации некоторых шаблонов PubSub. Вот пример:
Вот на что следует обратить внимание! Этот несвязанный режим отличается от componentwillunmount. componentwillunmount будет выполняться только один раз перед уничтожением компонента, а используемая функция effect будет выполняться один раз после каждого рендеринга компонента, включая функцию очистки, возвращаемую функцией побочного эффекта. Итак, давайте рассмотрим следующий вопрос.
Почему вы хотите, чтобы функция побочного эффекта выполняла каждое обновление компонента?
Давайте посмотрим на предыдущую модель:
Очень ясно, мы регистрируемся в componentDidMount, а затем очищаем регистрацию в componentWillUnmount. Но что, если реквизит. Друг. Идентификатор меняется в это время? Мы должны добавить еще один компонент didupdate, чтобы справиться с этой ситуацией:
Ты видел? Это утомительно, но у нас нет этой проблемы с эффектом использования, потому что он будет повторно выполняться после каждого обновления компонента. Таким образом, порядок выполнения кода выглядит следующим образом:
- Визуализация первой страницы
- Зарегистрируйтесь в качестве друга с
- Внезапно friend.id становится 2
- Повторный рендеринг страницы
- Четкая привязка для друга.
- Зарегистрируйтесь в качестве друга с
- …
Как пропустить некоторые ненужные функции побочных эффектов
Согласно идее, изложенной в предыдущем разделе, эти функции побочных эффектов должны выполняться один раз для каждого повторного рендеринга, что явно неэкономично. Как пропустить ненужные вычисления? Нам просто нужно передать второй параметр, чтобы использовать эффект. Используйте второй параметр, чтобы указать react выполнять переданную нами функцию побочного эффекта (первый параметр) только при изменении значения этого параметра.
Когда мы передаем пустой массив [] в качестве второго параметра, это эквивалентно выполнению только при первом рендеринге. То есть режим componentdidmount плюс componentwillunmount. Однако такое использование может привести к ошибкам и меньшему использованию.
Какие еще эффекты у вас есть?
использование Уменьшено
Use reducer-это API, подобный API, предоставляемый hooks, который позволяет нам управлять контекстом или состоянием посредством действий
//reducer.js
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'reset':
return initialState;
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
}
}
export default function Counter({initialCount}) {
const [state, dispatch] = useReducer( // const [state, dispatch] = useReducer(reducer, initialState);
reducer, initialState,
{type: 'reset', payload: initialcount}, //, the initial operation is applied during the initial rendering
);
return (
<>
Count: {state.count}
);
}пользовательский контекст
const(Контекст); Примите объект контекста (значение, возвращаемое из react.create context) и верните текущее значение контекста, которое предоставляется контексту последним поставщиком контекста. Когда поставщик обновляется, этот крючок запускает повторную визуализацию с последним значением контекста.
//reducer.js
import React, { useReducer } from "react";
const initialState = 0;
const myContext = React.createContext();
function reducer(state, action) {
switch (action.type) {
case "reset":
return initialState;
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
const ContextProvider = props => {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
{props.children}
);
};
export { reducer, myContext, ContextProvider };
//Counter.js
import React, { useContext } from "react";
import { myContext } from "./reducer";
function Counter() {
const { state, dispatch } = useContext(myContext);
return (
Counter Count: {state.count}
);
}
export default Counter;
//CounterTest.js
import React, { useContext } from "react";
import { myContext } from "./reducer";
function CounterTest() {
const { state, dispatch } = useContext(myContext);
return (
CounterTest Count: {state.count}
);
}
export default CounterTest;
//index.js
import React from "react";
import { ContextProvider } from "./reducer";
import Counter from "./Counter";
import CounterTest from "./CounterTest";
const App = () => {
return (
);
};
const rootElement = document.getElementById("root");
ReactDOM.render( , rootElement);В дополнение к состоянию использования и эффекту использования, контексту использования, редуктору использования и реакции, выделенным выше, мы также предоставляем множество полезных крючков:
- обратный вызов пользователя
- используйте памятку
- useRef
- используйте Императивные Методы
- используйте Эффект Мутации
- использовать Эффект Макета
Я не буду представлять их одного за другим. Вы можете самостоятельно ознакомиться с официальными документами.
Как написать пользовательские крючки эффектов?
Почему мы должны сами писать эффект? Таким образом, мы можем извлечь логику многократного использования и превратить ее в “контакты”, которые можно подключать и отключать по желанию. Какой компонент следует использовать, я подключу его к какому компоненту, так просто! Посмотрите на полный пример, и вы увидите.
Например, мы можем извлечь функцию оценки того, находится ли друг в Сети, из компонента статуса друга, описанного выше, и создать новый хук usefriendstatus, чтобы определить, находится ли идентификатор в сети.
В настоящее время компонент статуса друга может быть сокращен следующим образом:
Если у нас есть другой список друзей в это время, нам также необходимо отобразить информацию о том, находятся ли они в Сети:
Оригинал: “https://developpaper.com/react-hooks-function/”