Приветствую всех вОблако Tencent + сообщество, получить больше крупной технической практики Tencent по галантерее ~
Эта статья написанаЧжиханОпубликован вКолонка «Облако + сообщество»
TL;DR
Одним предложением React Hooks находится в функциональном компоненте реакции, вы также можете использовать состояние и жизненный цикл компонентов компонентов класса, не переключаясь между миксинами, функциональными компонентами, компонентами HOC и реквизитами рендеринга, создавая функциональные компоненты. практичнее, и нам удобнее реализовать разделение кода бизнес-логики и повторное использование компонентов в бизнесе.
В этой статье будут представлены хуки из следующих аспектов
Какие проблемы решают хуки Знакомство с API хуков и как использовать хуки Как реализованы хуки?
💡Какие проблемы решают хуки?
React решает проблему, как отделить код бизнес-логики и реализовать повторное использование связанной бизнес-логики внутри компонента.
Как правило, мы организуем большие пользовательские интерфейсы на наших страницах в независимые небольшие пользовательские интерфейсы с помощью компонентов и потока данных сверху вниз, чтобы добиться повторного использования компонентов. Но мы часто сталкиваемся с трудностями при вторжении в сложный компонент для повторного использования, потому что логика компонента зависит от состояния и не может быть извлечена в функциональный компонент. Это особенно часто встречается при работе с анимацией и формами, и когда мы подключаемся к внешним источникам данных в компоненте, а затем хотим выполнить больше других операций в компоненте, мы можем особенно сильно испортить компонент:
- Сложность повторного использования и совместного использования логики, связанной с состоянием, в компонентах, что приводит к большому количеству огромных компонентов.
- Компоненты со сложной логикой сложно разрабатывать и поддерживать.Когда нашим компонентам нужно иметь дело с несколькими несвязанными локальными состояниями, каждая функция жизненного цикла может содержать различную несвязанную логику.
- Сложные шаблоны, такие как свойства рендеринга и компоненты более высокого порядка.
- Из-за изменений в бизнесе функциональные компоненты пришлось заменить компонентами класса.
Здесь на помощь приходят крючки. Хуки позволяют нам организовать логику внутри компонента в многоразовый изолированный модуль.
Чтобы проиллюстрировать проблему с двумя диаграммами @Sunil Pai:
То, что мы испытываем от React Hooks, — это реализация философии React внутри компонентов.В прошлом мы только напрямую отражали философию React в компонентах и компонентах, то есть четкий и понятный поток данных и композиция. Логику в компоненте можно переиспользовать, а привнесенные HOC слои вложенности не появятся, и он не появится.Недостатки Миксина.
💡Введение в API хуков и как использовать хуки
@dan_abramov познакомил нас с тремя ключевыми API хуков на конференции, а именноState Hooks,Effect Hooks,Custom Hooks(自定义hooks)
📌 Хуки состояния (useState)
Метод useState переносит в наш функциональный компонент локальное состояние, принимает значение начального состояния и возвращает пару переменных. Пусть функциональные компоненты имеют свои собственные компоненты.
Прежде всего, что, если нам нужно использовать компонент классов для реализации компонента «Кнопка нажатия +1»?
import React from 'react';
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {count: 0};
this.clickBtn = this.clickBtn.bind(this);
}
clickBtn = () => {
this.setState({
count: this.state.count + 1;
});
}
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={this.clickBtn}>
Click me
</button>
</div>
);
}
Итак, на что похоже использование useState? Это видно очень четко.
// 一个简单的点击计数
import { useState } from 'react';
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
📌Крюки эффектов (useEffect)
Хуки эффектов используются для обработки некоторых операций с побочными эффектами.Ниже приведен пример использования хуков эффектов для отслеживания изменения ширины окна.
import { useState } from 'react';
function windowWidth() {
const [width, setWithd] = useState(window.innerWidth);
useEffect(() => {
const handleResize = ()=>{
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
});
return (
<p> window width is {width}</p>
)
}
useEffect может передать вторую операцию, чтобы избежать потери производительности.Если переменные-члены во втором массиве параметров не изменились, это изменение будет пропущено. Как передать пустой массив, тогда эффект будет выполняться только в период монтирования и размонтирования компонента.
import { useState } from 'react';
function windowWidth() {
const [width, setWithd] = useState(window.innerWidth);
useEffect(() => {
const handleResize = ()=>{
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
}, [width]); // width 没有变化则不处理
return (
<p> window width is {width}</p>
)
}
В useEffect вы также можете выполнять некоторые операции очистки, такие как отмена совместимости, позволяя функции возвращать функцию, например отмену подписки и т. д.
import { useState } from 'react';
function windowWidth() {
const [width, setWithd] = useState(window.innerWidth);
useEffect(() => {
const handleResize = ()=>{
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
return () => {
// 取消监听窗口的宽度变化
window.removeEventListener('resize');
}
});
return (
<p> window width is {width}</p>
)
}
Как показано выше, встроенные хуки React, такие как useState и useEffect, выступают в качестве основных строительных блоков. Мы можем использовать их непосредственно в компоненте или объединить их в пользовательский хук, например useWindowWidth. Использование пользовательских хуков похоже на использование встроенного API React.
📌Пользовательские хуки пользовательских компонентов
Помимо приведенного выше кода для контроля размера окна, давайте поговорим о пользовательских хуках,Продемонстрируйте, как реагирующие хуки делают логику внутри компонентов многократно используемой.
Talk is cheap, show me the code.
// 一个显示目前窗口大小的组件
function responsiveComponent(){
// custom hooks
const width = useWindowWidth();
return (
<p>当前窗口的宽度是 {width}</p>
)
}
Приведенный выше код состоит всего из нескольких строк, и совершенно ясно, что его роль заключается в прослушивании изменений в текущем окне, что и является целью хуков — сделать компоненты действительно декларативными, даже если они содержат состояние и побочные эффекты.
Давайте посмотрим, как реализовать этот пользовательский хук. Мы используем собственное состояние React, чтобы сохранить текущую ширину окна, и используем побочные эффекты, чтобы установить это состояние при изменении размера окна.
import { useState, useEffect} from 'react';
// custom hooks to listen window width change
function useWindowWidth(){
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = ()=>{
setWidth(window.innerWidth);
}
window.addEventListener('resize', handleResize);
}, [width]); // width 没有变化则不处理
return width;
}
[Пример онлайн-редактирования]
⚡ Правила для React Hooks
Хуки — это функции JavaScript, но они накладывают два дополнительных правила:
- только вверхний этажПозвоните Хуксу. Не вызывайте хуки в циклах, условных выражениях или вложенных функциях.
- Вызывайте хуки только из функциональных компонентов React. Не вызывайте хуки из обычных функций JavaScript. (Есть еще одно место для вызова хуков — ваши собственные хуки.)
🔌 Другие крючки
Вот несколько менее часто используемых встроенных хуков. Например, useContext позволяет вам подписываться на контексты React без вложенности:
function Example() {
const locale = useContext(LocaleContext);
const theme = useContext(ThemeContext);
// ...
}
Нашел очень интересный склад,react-use, содержит много интересных пользовательских хуков
👀Как работают крючки
Далее переводится сreact-hooks-not-magic-just-arrays.
хуки реакции на самом деле просто массив, а не магия.
Как добитьсяuseState()метод
Давайте рассмотрим пример, чтобы продемонстрировать, как работает реализация перехватчиков состояния.
Сначала начнем с компонента:
function RenderFunctionComponent() {
const [firstName, setFirstName] = useState("Rudi");
const [lastName, setLastName] = useState("Yardley");
return (
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
);
}
Идея API хуков заключается в том, что вы можете использовать функцию установки для возврата в качестве второго элемента массива в функции хука, и установщик будет контролировать состояние, управляемое хуком.
Так при чем здесь React?
Давайте разберемся, как это работает внутри React. Следующее может использоваться в контексте выполнения для рендеринга определенного компонента. Это означает, что данные, хранящиеся здесь, находятся вне визуализируемого компонента. Это состояние не используется совместно с другими компонентами, но сохраняется в области видимости, в которой конкретный компонент затем может быть отображен.
1) Инициализировать
Создайте два пустых массива:settersа такжеstate
установить курсор на 0
Инициализация: два пустых массива, курсор равен 0
2) Первый рендер
Запустите функцию компонента в первый раз.
Каждый вызов useState() при первом запуске помещает функцию установки (привязанную к положению курсора) в массив установок, а затем помещает некоторое состояние в массив состояний.
Первый рендеринг: элементы записываются в массив по мере увеличения курсора.
3) Последующий рендеринг
Каждый последующий рендер сбрасывает курсор и считывает только эти значения из каждого массива.
Последующий рендеринг: элемент, прочитанный из массива, является приращением курсора
4) Обработка событий
Каждый установщик имеет ссылку на позицию своего курсора, поэтому вызов любого установщика изменит значение состояния в этой позиции в массиве состояний.
Сеттеры «запоминают» свой индекс и устанавливают память в соответствии с ним.
Реализация функциональности useState через псевдокод
Вот пример кода, демонстрирующий реализацию:
let state = [];
let setters = [];
let firstRun = true;
let cursor = 0;
function createSetter(cursor) {
return function setterWithCursor(newVal) {
state[cursor] = newVal;
};
}
// useState的伪代码实现
export function useState(initVal) {
if (firstRun) {
state.push(initVal);
setters.push(createSetter(cursor));
firstRun = false;
}
const setter = setters[cursor];
const value = state[cursor];
cursor++;
return [value, setter];
}
// 模拟使用useState
function RenderFunctionComponent() {
const [firstName, setFirstName] = useState("Rudi"); // cursor: 0
const [lastName, setLastName] = useState("Yardley"); // cursor: 1
return (
<div>
<Button onClick={() => setFirstName("Richard")}>Richard</Button>
<Button onClick={() => setFirstName("Fred")}>Fred</Button>
</div>
);
}
// 模拟Reacts渲染周期
function MyComponent() {
cursor = 0; // 重置光标的位置
return <RenderFunctionComponent />; // render
}
console.log(state); // Pre-render: []
MyComponent();
console.log(state); // 首次渲染: ['Rudi', 'Yardley']
MyComponent();
console.log(state); // 后续渲染: ['Rudi', 'Yardley']
// 点击'Fred' 按钮
console.log(state); // 点击后: ['Fred', 'Yardley']
Суммировать
Хуки все еще находятся на ранней стадии, но они дают нам хорошее представление о логике повторного использования компонентов, которую вы можете испытать в react-16.7.0-alpha.0.
Связанное Чтение [Ежедневная рекомендация курса] Машинное обучение в действии! Быстрый старт бизнеса в сфере онлайн-рекламы и знание CTR
Эта статья была разрешена автором для публикации в сообществе Tencent Cloud + Для получения дополнительных оригинальных текстов, пожалуйстанажмите
Найдите и подпишитесь на общедоступную учетную запись «Сообщество Yunjia», получите технические галантереи как можно скорее и ответьте на 1024 после подписки, чтобы отправить вам подарочный пакет технических курсов!
Огромный технический практический опыт, все вСообщество Юнцзя!