❝Британский поэт Сассун в поэзии «Я, Прошлое, Существование Настоящее и Будущее» пишет: «В me the tiger sniffs the rose" Поэт Юй Гуанчжун перевел это как: «С тигром в сердце я осторожно вдыхаю запах розы». ❞
Всем привет,Я«Семь, восемь, девять»。
сегодня,Давайте продолжим«Фронтальное интервью»из Очки знаний。давайте поговорим о«Реагировать на практике»из相关Очки знанийиспецифическийизалгоритм。
Большинство статей этой серии представляют собой краткое изложение знаний из предыдущих статей. Если вы хотите узнать больше о соответствующем содержании, перейдите к соответствующей серии для обсуждения.
Если вы хотите узнать больше об этой серии статей, вы можете обратиться к статьям, которые мы опубликовали. Ниже приведены прошлые статьи.
Ладно, уже поздно, давайте приступим к делу.
❝
❞
TypeScript
что такое❝
TypeScript
Это язык программирования с открытым исходным кодом Microsoft. этоJavaScript
из⼀индивидуальный«Суперсет»。 по существу в сторонуJS
Добавлен опциональноиз
❞
TypeScript
Предоставляйте новейшие и развивающиеся JavaScript
недвижимость, в том числе из 2015 ежегодный ECMAScript и функции в будущих предложениях, такие как асинхронная функциональность и Decorators
,Чтобы помочь создать надежные компоненты.
TypeScript
и JavaScript
РазницаTypeScript | JavaScript |
---|---|
«Расширенный набор» JavaScript, используемый для решения проблемы сложности кода в крупных проектах. | «Язык сценариев» для создания динамических веб-страниц. |
Ошибки можно найти и исправить «во время компиляции». | Поскольку это «интерпретируемый язык», ошибки можно обнаружить «только» во время выполнения. |
«Строгая типизация», поддерживает статические и динамические типы. | «Слабая типизация», нет опции статической типизации. |
Наконец, скомпилирован в код JavaScript, чтобы браузер мог его понять. | Можно использовать прямо в браузере |
Модули поддержки, дженерики и интерфейсы | Нет поддержки дженериков или интерфейсов. |
Включено в изображение выше 3 индивидуальный ts ⽂куски:a.ts
、b.ts
и c.ts
。Эти⽂куски Воля被 TypeScript
Компилятор, скомпилированный в соответствии с настроенными параметрами компиляции в 3 индивидуальный js файл, т.е. a.js
、b.js
и c.js
。для⼤большинство делает⽤ TypeScript
развитый Web проект, мы также скомпилируем и сгенерируем js ⽂куски进⾏«Упаковка»,Затем разворачивается существование.
TypeScript имеет три основные функции:
TypeScript
Может скомпилировать чистый, краткий JavaScript
код,и Может бежатьсуществоватьв любом браузере、Node.js
окружение и любая поддержка ECMAScript 3
(илиболее поздняя версия)изJavaScript в двигателе.JavaScript
Разработано существование JavaScript
При подаче заявки используйте эффективные инструменты разработки и стандартные операции, такие как статическая проверка и рефакторинг кода.TypeScript
Предоставляйте новейшие и развивающиеся JavaScript
недвижимость, в том числе из 2015 ежегодный ECMAScript из Функции в будущих предложениях, такие как асинхронные функции Декораторы, помогающие создавать надежные компоненты.❝Общий относится кизда«Параметризация типа»:Вот-вот получится что-то«Параметризация конкретных из типов» ❞
вроде C++
/Java
/Rust
Такой OOP
на языке,Может«Используйте дженерики для создания повторно используемых компонентов, которые могут поддерживать несколько типов данных».。 Таким образом, пользователи могут использовать компоненты со своими собственными типами данных.
❝Дженерики дизайнаиз「Ключ」дасуществовать«Обеспечьте значимые ограничения между участниками»,Эти成员Можетда:добрыйиз Члены экземпляра、Метод класса、Параметры функции и функция получают значение. ❞
Типы TypeScript
и объект JavaScript
руководить Сравнивать。
❝основнойиз"разница"да
JavaScript
середина,заботаизда变量из"ценить"TypeScript
середина,заботаизда变量из"тип"❞
Но длянасизUser
Например,Используйте одининдивидуальный"Общий"смотреть起来да Такой。
// `User` Сейчас существуют — это родовой тип
const user: User<'существовать Проволока' | 'оффлайн'>;
// Мы можем вручную добавить нового человека нового типа. (праздный)
const user: User<'существовать Проволока' | 'оффлайн' | 'праздный'>;
Что сказано выше user
«Переменная имеет типUser
изобъекта"。
Давайте продолжим来实сейчасэтотиндивидуальный"тип"。
// Определение универсального типа
type User<StatusOptions> = {
name: string;
status: StatusOptions;
};
StatusOptions
называется тип типа переменной переменная, в то время как User
говорили, что это Общий тип универсальный type。
Обычно ситуация такая,когда ты хочешь«Один тип существования является общим для многих индивидуальных экземпляров, и каждый индивидуальный экземпляр в чем-то отличается».:Вот этоиндивидуальныйдобрый型да"динамичный"из。
Во-первых, давайте определим индивидуального Генерал з identity
функция,функцияиз「возвращатьсяценитьиздобрый型」иэтоиз«Параметры те же»
Наша цель – сделать identity
функция Может适⽤В«Любой конкретный тип»,для Для достижения этой цели,нас Может使⽤"Общий"решить этоиндивидуальныйвопрос,Конкретный метод реализации заключается в следующем:
function identity <T>(value: T) : T {
return value;
}
console.log(identity<Number>(1)) // 1
Видеть <T>
язык法,Сразу「Параметры передачи карты такие же」,Приведенный выше код передает тип, который мы хотим использовать для вызова определенной функции.
也Может引⼊определение надеждыиз«Любое количество переменных типа»。⽐нравитьсянас引⼊⼀индивидуальныйновыйиздобрый型变量 U
, используемый для расширения нашего определения identity
функция:
function identity <T, U>(value: T, message: U) : T {
console.log(message);
return value;
}
console.log(identity<Number, string>(68, «ТС такой вкусный»);
иногданас可能希望«Ограничить количество типов, принимаемых каждой переменной типа индивидуальный»,этот Сразуда「Общие ограничения」изделать⽤。Вниз⾯нас来举⼏индивидуальныйпример⼦,Расскажите, как использовать общие ограничения.
иногда,нас希望«Переменные типа соответствуют определенным атрибутам, хранящимся в типе».。В это время,Если мы явно не определим конкретный атрибут как переменную типа для,В противном случае компилятор не узнает об их существовании.
Например, при работе со строками или массивами мы предполагаем length
Свойства доступны. Давайте использовать его снова identity
функцию и попробуйте вывести длину аргумента:
function identity<T>(arg: T): T {
console.log(arg.length); // Error
return arg;
}
существуют В этом случае,«Компилятор»не буду знать T
содержит length
свойство,尤其дасуществовать Может«Присвойте любой тип переменной типа T из情况Вниз」。нас需хотеть Делатьиз Сразудапозволятьдобрый型变量 extends
⼀индивидуальный содержит необходимые нам атрибуты интерфейса, например:
interface Length {
length: number;
}
function identity<T extends Length>(arg: T): T {
console.log(arg.length); // Вы можете получить атрибут длины
return arg;
}
T extends Length
Используется, чтобы сообщить компилятору, что наша поддержка реализована. Length
Любой тип интерфейса.
В предыдущих примерах мы показали только, как использовать дженерики для определения синтаксиса обычных функций, а не синтаксиса стрелочных функций, представленного в ES6.
// ES6 из синтаксиса стрелочной функции
const identity = (arg) => {
return arg;
};
Если вы хотите работать со стрелочными функциями, вам необходимо использовать следующий синтаксис.
// Путь 1
const identity = <ArgType,>(arg: ArgType): ArgType => {
return arg;
};
// Способ 2
const identity = <ArgType extends unknown>(arg: ArgType): ArgType => {
return arg;
};
出сейчас上述вопросизисточниксуществовать В:「этотдаTSX
(TypeScript
+ JSX
)из特定язык法」。существоватьнормальныйиз TypeScript
, нет необходимости использовать этот обходной путь.
❝существоватьбольшинство из них,
TS
都Может根据hook
серединаизценить来сделать выводэто们издобрый型:也Сразуданас常说из「вывод типа」 ❞
чтодлявывод типа,Проще говоря:「вывод типа」Сразуда«Возможность вывести тип на основе выражения присваивания»。ts
采использовать Волядобрый型отметка声明放существоватьпосле переменных(Прямо сейчас«Введите постфикс»)изспособ работы с переменнымииздобрый型руководитьотметка。И сделать⽤«Введите постфикс аннотации»из好处Сразудакомпилировать器Можетпроходитькод所существоватьиз«Контекст выводит соответствующий тип»,Нет необходимости снова объявлять тип переменной.
картина
都Может根据«Контекстуальный вывод»публично заявить。
Например,Вниз面изкод Можетсуществоватьts
环境серединанормальный运行,и способенпроходитьвывод типаполученныйname
издобрый型дляstring
добрый型。
const [name, setName] = useState('Передняя часть Цибацзю');
В следующих двух ситуациях вывод типа бесполезен.
ts
предполагаемыйиздобрый型«Слишком свободный»нас Доизпримерребенок--иметьодининдивидуальный字符串добрый型изname
。ноданас假设этотиндивидуальныйname
只能иметьдваиндивидуальный«Резервная стоимость»серединаизодининдивидуальный。
существуют В этом случае,насвстреча希望name
иметьодининдивидуальный非常специфическийиздобрый型,Напримерэтотиндивидуальныйдобрый型。
type Name = 'Передняя часть Цибацзю' | «Внешний инженер» ;
Этот тип использует как типы объединения, так и литеральные типы.
существуют В этом случае,сделать выводиздобрый型«Слишком свободный»(даstring
,Вместо этого нам нужна из2индивидуальная строка из определенного подмножества),В этом случае тип необходимо указать самостоятельно.
const [name, setName] = useState<Name>('Передняя часть Цибацзю');
иногда,сделать выводиздобрый型да错误из(или ВОЗ«Слишком ограничительный»不даты想хотетьиздобрый型)。этот种情况经常发生существоватьReact
изuseState
«значение по умолчанию»середина。Например,name
из初始ценитьдаnull
。
const [name, setName] = useState(null);
существуют В этом случае,TypeScript
встречапредполагаемыйname
данулевой тип
из(этот意味着это«Всегда ноль»)。этот显然да错误из:наскназадвстречахочу name
Установите отдельную строку.
В этот момент вы должны сказать TypeScript
,Это могут быть и другие виды.
const [name, setName] = useState<string | null>(null);
После обработки следующим образом,TypeScript
встреча正确理解name
Можетдаnull
也Можетдаstring
。
❝Здесь следует упомянуть, что,«Когда вывод не работает,Следует полагаться на общие параметры вместо утверждений типа"。
const [name, setName] = useState<Name>('Передняя часть Цибацзю');
«Рекомендую»const [name, setName] = useState('Передняя часть Цибацзю' as Name);
«Не рекомендуется»❞
существовать Передний,Мы уже говорили об этом,нравитьсячтоиметь дело сuseState
изразличные ситуации。этот里Сразу不существоватьнеоднократно。
const [name, setName] = useState<string | null>(null);
useReducer
соотношение типов useState
хотеть复杂один些。на самом делеuseState
СразудаuseReducer
из Упрощенная версия。
противuseReducer
иметьдва样东西хотеть「Ввод текстаиметь дело с」:state
иaction
。
этот里иметьодининдивидуальныйuseReducer
из简单примерребенок。противinput
Сделайте это простоизданные收集иметь дело с。
import { useReducer } from 'react';
const initialValue = {
username: '',
email: '',
};
const reducer = (state, action) => {
switch (action.type) {
case 'username':
return { ...state, username: action.payload };
case 'email':
return { ...state, email: action.payload };
case 'reset':
return initialValue;
default:
throw new Ошибка(`Неопределенное действие: ${action.type}`);
}
};
const Form = () => {
const [state, dispatch] = useReducer(reducer, initialValue);
return (
<div>
//....
</div>
);
};
export default Form;
У нас есть два варианта Ввода текстаreducer-state
。
typeof
Операторconst initialValue = {
username: '',
email: '',
};
+ const reducer = (state: typeof initialValue, action) => {
///....
};
+type State = {
+ username: string;
+ email: string;
+};
+ const reducer = (state: State, action) => {
// ....
};
reducer-action
соотношение типовreducer-state
хотеть难один点,потому чтодляэтоиз«Структура будет зависеть от конкретнойaction
и измениться»。
Например, для username-action
,Мы могли бы ожидать следующих типов.
type UsernameAction = {
type: 'username';
payload: string;
};
Но для reset-action
,нас不需хотетьpayload
Поле。
type ResetAction = {
type: 'reset';
};
нас Может借助«Тип Союза»относиться к разным по-разномуизaction
。
const initialValue = {
username: "",
email: ""
};
+type Action =
+ | { type: "username"; payload: string }
+ | { type: "email"; payload: string }
+ | { type: "reset" };
+ const reducer = (state: typeof initialValue, action: Action) => {
//....
};
Тип действия
выражатьизда,это Можетпринимать联合добрый型середина包含из«Любой из трех типов»。потому что此,если TypeScript
Видеть action.type
даusername
,он автоматически узнает, что это должен быть первый случай,иpayload
应该даодининдивидуальныйstring
。
❝проходитьверно
state/action
Ввод текстаназад,useReducer
способен начать сreducer
функцияизtype
серединапредполагаемыйэто需хотетьизодин切。 ❞
useRef
Есть два основных варианта использования
Это в основном и useState
такой же。хочуuseRef
保житьодининдивидуальный Настроитьизценить,Вам нужно сказать это этому индивидуальному типу.
function Timer() {
+ const intervalRef = useRef<number | undefined>();
useEffect(() => {
const id = setInterval(() => {
// ...
});
intervalRef.current = id;
return () => {
clearInterval(intervalRef.current);
};
});
// ...
}
существоватьDOMузел上использоватьuseRef
изодининдивидуальный经典использоватьпримердаиметь дело сinput
элементизfocus
。
mport { useRef, useEffect } from 'react';
const AutoFocusInput = () => {
+ const inputRef = useRef(null);
useEffect(() => {
+ inputRef.current.focus();
}, []);
+ return <input ref={inputRef} type="text" value="Передняя часть Цибацзю" />;
};
export default AutoFocusInput;
TypeScript
иметь«Встроенный тип элемента DOM»。Этидобрый型из结构общийдатакой жеиз:
❝если
name
даты正существоватьиспользоватьиз"HTML-тег имени",соответствующийиздобрый型ВолядаHTML${Name}Element
。 Вот некоторые особые случаи
<a>
Этикеткаиздобрый型дляHTMLAnchorElement
<h1>
Этикеткаиздобрый型дляHTMLHeadingElement
❞
для<input>
,该добрый型из名称ВолядаHTMLInputElement
。
mport { useRef, useEffect } from 'react';
const AutoFocusInput = () => {
+ const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
+ inputRef.current?.focus();
}, []);
return <input ref={inputRef} type="text" value="Передняя часть Цибацзю" />;
};
export default AutoFocusInput;
"Уведомление":существоватьinputRef.current?.focus()
上加Понятноодининдивидуальный?
。этотдапотому чтодлядля TypeScript
,inputRef.current
«Может быть, это Сора»。существуют В этом случае,Мы знаем, что оно не будет пустым,потому чтодляэтодасуществовать useEffect
Перед первым запуском React
Заполненный.
иногдахочуref
вперед кподкомпонент。хотеть Делатьприезжатьэтотодин点,существовать React
в мы должны использовать forwardRef
来«Компоненты упаковки»。
import { ChangeEvent } from 'react';
type Props = {
value: string,
handleChange: (event: ChangeEvent<HTMLInputElement>) => void,
};
const TextInput = ({ value, handleChange }: Props) => {
return <input type="text" value={value} onChange={handleChange} />;
};
Например,житьсуществоватьодининдивидуальный组кускиTextInput
инас想существовать父组кускиизместо звонка,проходитьref
контролироватьподкомпонентinput
。
в это время,Сразу需хотетьиспользоватьforwardRef
来иметь дело с。
import { forwardRef, ChangeEvent } from 'react';
type Props = {
value: string;
handleChange: (event: ChangeEvent<HTMLInputElement>) => void;
};
+const TextInput = forwardRef<HTMLInputElement, Props>(
+ ({ value, handleChange }, ref) => {
return (
+ <input ref={ref} type="text" value={value} onChange={handleChange} />
);
}
);
Этот синтаксис требует только forwardRef
поставлятьдолжноожиданияизHTMLElement
(существуют В этом случаедаHTMLInputElement
)。
❝«Есть одна вещь, на которую следует обратить внимание».:组кускипараметр
ref
иprops
иззакази Дженерикииз<HTMLInputElement, Props>
不один样。 ❞
❝«Вам не обязательно давать им какой-либо тип» ❞
唯один需хотеть Уведомлениеизда«Неявный возврат»。useEffect
виз Обратный вызов долженчто такое Ни одинвозвращаться,или ВОЗдаодининдивидуальныйвстреча清理任что副делатьиспользоватьизDestructor
функция(«Деструктор»,Это слово индивидуальный заимствовано из оператора класса C++)
❝«Вам не обязательно давать им какой-либо тип» ❞
дляcontext
поставлятьдобрый型да非常容易из。первый,дляcontext
из"ценить"создаватьодининдивидуальныйдобрый型,然назад把этоделатьдляодининдивидуальный"Общий"поставлять ДаватьcreateContext
функция。
import React, { createContext, useEffect, useState, ReactNode } from 'react';
+type User = {
+ name: string;
+ email: string;
+ freeTrial: boolean;
+};
+type AuthValue = {
+ user: User | null;
+ signOut: () => void;
+};
+const AuthContext = createContext<AuthValue | undefined>(undefined);
type Props = {
children: ReactNode;
};
const AuthContextProvider = ({ children }: Props) => {
const [user, setUser] = useState(null);
const signOut = () => {
setUser(null);
};
useEffect(() => {
// Лечение побочных эффектов
}, []);
return (
+ <AuthContext.Provider value={{ user, signOut }}>
{children}
+ </AuthContext.Provider>
);
};
export default AuthContextProvider;
один旦ты向createContext
поставлять Понятно Дженерики,Остальные вещи,Все поts
для Ты делаешь это для меня。
Проблема с приведенной выше индивидуальной реализацией заключается в том,,СразуTypeScript
с точки зрения,context
изценить Можетда未определениеиз。也Сразудасуществоватьнасиспользоватьcontext
изценитьизкогда,Он может быть недоступен. в это время,ts
可能встреча阻拦кодизкомпилировать。
нравитьсячто解决context
изценить可能да未определениеиз Какова ситуация?。наспротивcontext
из获取Может Используйте одининдивидуальный「Настроитьhook
。」
export const useAuthContext = () => {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Ошибка('useAuthContext должен использоваться в контексте AuthContext');
}
return context;
};
проходить«Тип защиты»,使得нассуществоватьиспользоватьcontext
изкогда,Всегда есть ценность из.
❝「Ввод текста Настроить
hook
по сутии Ввод Текст То же, что и обычные функции" ❞
先иметь дело сonClick
事куски。React
поставлять Понятноодининдивидуальный MouseEvent
Типа, вы можете использовать его напрямую!
import {
useState,
+ MouseEvent,
} from 'react';
export default function App() {
// Опустить часть кода
+ const handleClick = (event: MouseEvent) => {
console.log('Отправка сработала');
};
return (
<div className="App">
<h1>Передняя часть Цибацзю</h1>
<button onClick={handleClick}>представлять на рассмотрение</button>
</div>
);
}
❝
onClick
事куски实际上да由React
поддерживатьиз:этодаодининдивидуальный«Синтетическое событие»。 合成事кускидаReact
верно«События браузера — это оболочка,Чтобы разные браузеры,У всех одинаковый API。 ❞
handleInputChange
функцияи handleClick
очень похоже,Но есть очевидное различие. Разница в том,,ChangeEvent
даодининдивидуальный"Общий",ты«Необходимо указать, какой элемент изDOM используется»。
import {
useState,
+ ChangeEvent
} from 'react';
export default function App() {
const [inputValue, setInputValue] = useState('');
+ const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
};
// Опустить часть кода
return (
<div className="App">
<h1>Передняя часть Цибацзю</h1>
<input value={inputValue} onChange={handleInputChange} />
</div>
);
}
существуют Одна вещь, на которую вам нужно обратить внимание в приведенном выше коде, это то, что,HTMLInputElement
В частности, относится к входному тегу HTML. Если мы используем textarea
,нас Воляиспользовать HTMLTextAreaElement
заменить.
Уведомление,MouseEvent
Также является индивидуальным дженериком, вы можете существовать и руководить ограничениями на него при необходимости. Например, возьмем вышеизложенное MouseEvent
Ограничение на отправку событий мыши исключительно с отдельной кнопки.
const handleClick = (event: MouseEvent<HTMLButtonElement>) => {
console.log('Отправка сработала');
};
Все еще нужно напоминание из-за,React
длянаспоставлять Понятно很много Event
Объявление типа объекта.
тип события | объяснять |
---|---|
ClipboardEvent<T = Element> | Объект события буфера обмена |
DragEvent<T =Element> | перетащить объект события |
ChangeEvent<T = Element> | «Изменить объект события» |
KeyboardEvent<T = Element> | объект события клавиатуры |
MouseEvent<T = Element> | «Объект события мыши» |
TouchEvent<T = Element> | сенсорный объект события |
WheelEvent<T = Element> | объект времени колеса |
AnimationEvent<T = Element> | Объект события анимации |
TransitionEvent<T = Element> | объект события перехода |
React
Заявление, предоставленное документом EventHandler
Введите псевдонимы для разных событий EventHandler
из«Введите псевдоним»来определение事кускииметь дело сфункцияиздобрый型,Удобнее определить тип ее функции.
import {
useState,
+ ChangeEventHandler,
+ MouseEventHandler
} from 'react';
export default function App() {
const [inputValue, setInputValue] = useState('');
+ const handleInputChange: ChangeEventHandler<HTMLInputElement> = (event) =>{
setInputValue(event.target.value);
};
+ const handleClick: MouseEventHandler = (event) => {
console.log('Отправка сработала');
};
return (
// ... упущение....
);
}
ты也Можетполагаться на「вывод типа」,Вам не нужно обрабатывать эту функцию самостоятельно. но,ты需хотеть«Встроенная обработка функций обратного вызова»。
import { useState } from 'react';
export default function App() {
const [inputValue, setInputValue] = useState('');
return (
<div className="App">
<h1>Передняя часть Цибацзю</h1>
<input
value={inputValue}
+ onChange={(event) => setInputValue(event.target.value)}
/>
<button
+ onClick={(event) => console.log('Отправка сработала')}
>
представлять на рассмотрение
</button>
</div>
);
}
существовать React
Доступны две формы
И существующие компоненты класса должны наследовать Component
class Welcome extends React.Component {
render() {
return <h1>Hello, Передняя часть Цибацзю</h1>;
}
}
PureComponent
:встречаверно props
и state
руководить«Короткое сравнение»,Пропустить ненужное извозобновление,Улучшите производительность компонентов.
Можно сказать PureComponent
и Component
В принципе то же самое, но PureComponent
встреча浅Сравнивать,也Сразуда«Меньше рендерингиз»,такPureComponent
один般использовать В性能优化。
class Welcome extends React.PureComponent {
render() {
return <h1>Hello, Передняя часть Цибацзю</h1>;
}
}
существоватьжизненный циклсерединаиметьодининдивидуальный shouldComponentUpdate()
функция,shouldComponentUpdate()
если被определение,Сразувстречаверноновый旧 props
、state
руководить shallowEqual
Сравнивать,«Если старое и новое несовместимы, будет запущено обновление».。
也Можетэтот么理解:PureComponent
проходить«Принеси свое»из props
и state
из浅Сравнивать实сейчас ПонятноshouldComponentUpdate()
,этот点Component
не обладает。
❝
PureComponent
可能встречапотому что«Глубокая несогласованность данных»и выдать ошибкуизотрицательное суждение,что приводит кshouldComponentUpdate
результатвозвращатьсяfalse
,Интерфейс не возобновляется,Используйте с осторожностью. ❞
memo
:комбинированный pureComponent
Чистые компоненты componentShouldUpdate()
Функция,встречаверновходящийиз 「props
」 руководить сравнивается один раз, а затем на основе второго индивидуального значения функции появляется дальнейшее определение того, какие реквизиты требуют возобновления
❝Будьте осторожны
memo
даодининдивидуальный«Компоненты высокого уровня»,Могут использоваться как функциональные компоненты, так и компоненты классов. ❞
memo
Получите два индивидуальных параметра:
function MyComponent(props) {
}
function areEqual(prevProps, nextProps) {
}
export default React.memo(MyComponent, areEqual);
(pre, next) => boolean
,true
не будет обновлятьсяfalse
возобновлятьpre
:Доизданныеnext
:сейчассуществоватьизданныеReact.memo
и PureComponent
Разница:
PureComponent
Компоненты класса обслуживания,React.memo
既Может Компоненты класса обслуживание, также может обслуживать и функциональные компоненты,useMemo
Обслуживание функциональных компонентовPureComponent
противиздаprops
иstate
React.memo
"Только"противprops
来决定да否рендеринг❝
React.memo
извторойиндивидуальныйпараметризвозвращатьсяценитьиshouldComponentUpdate
извозвращатьсяценитьда相反из
React.memo
:возвращаться true Компоненты не рендерятся , возвращаться false Рендеринг компонентов.shouldComponentUpdate
: возвращаться true рендеринг компонентов , возвращаться false Компоненты не рендерятся❞
forwardRef
:«Передать по ссылке»,даодин种проходить组куски向«Подкомпонент»Автоматически передавать ссылкиref
изтехнология。
существовать React
середина,React
«Не допускаетсяref
проходитьprops
передача",потому чтодляref
да组кускисередина固定житьсуществоватьиз,существуют процессы регулировки компонентов,будут рассматриваться специально,иforwardRef
Сразудадля Понятно解决этоткуски事и诞生из,позволятьref
Можетпроходитьprops
передача。
// подкомпонент
const FancyButton = React.forwardRef((props, ref) => (
<button ref={ref} >
{props.children}
</button>
));
// В пределах родительского компонента
const ref = React.createRef();
<FancyButton ref={ref}>Кто нажимает на меня!</FancyButton>;
существовать16.0
назад,Официально запущенFragment
концепция фрагмента,能够позволять「одининдивидуальный组кускивозвращатьсямногоиндивидуальныйэлемент」,React.Fragment
等价В<></>
<></>
издругойFragment
Этому индивидуальному компоненту можно присвоить значение key
,Это индекс,<></>
不能赋ценитьlazy
:позволятьтыопределениеодининдивидуальный动态加载组куски,этот样иметь助В缩减 bundle
изобъем,И задержка загрузки существовала в первый раз, когда рендеринг не использовал компонент,То есть отложенная загрузка компонентов (компонентов высокого порядка).
lazy
接收одининдивидуальныйфункция,этотиндивидуальныйфункция需хотеть动态调использоватьimport()
,нравиться:
const SomeComponent = React.lazy(
() => import('./SomeComponent')
);
lazy
должен«Принять индивидуальную функцию»,нужновозвращатьсяодининдивидуальныйPromise
, нужно resolve
одининдивидуальный default
одининдивидуальныйКомпоненты реагирования
,lazy
долженхотеть配合Suspense
один起использоватьSuspense
:позволять组куски"ждать"определенныйиндивидуальный异步组куски操делать,Пока асинхронная операция не завершится.
const OtherComponent = React.lazy(
() => import('./OtherComponent')
);
function MyComponent() {
return (
// существованиеOtherComponent загружается до отображения Spinner
<React.Suspense fallback={<Spinner />}>
<OtherComponent />
</React.Suspense>
);
}
Profiler
:этотиндивидуальный组кускииспользовать В性能检测,Может检测один次react
рендеринг компонентовчасиз Накладные расходы на производительность
Этот компонент имеет два параметра:
id
:логотипProfiler
из唯один性onRender
:回调функция,组кускисуществоватьcommit
этап называетсяrender(
<App>
<Profiler id="Navigation" onRender={callback}>
<Navigation {...props} />
</Profiler>
<Main {...props} />
</App>
);
StrictMode
:строгий режим,это инструмент для выявления потенциальных проблем в приложениях
и Fragment
один样,StrictMode
Никакого существующего уровня пользовательского интерфейса не будет, только проверка и предупреждение.
import React from 'react';
function ExampleApplication() {
return (
<div>
<Header />
<React.StrictMode>
<div>
<ComponentOne />
<ComponentTwo />
</div>
</React.StrictMode>
<Footer />
</div>
);
}
В приведенном выше коде только ComponentOne
иComponentTwo
руководитьисследовать。
Обнаружение по следующим аспектам:
findDOMNode
из ПредупреждениеJSX
встреча被компилироватьдляReact.createElement
изформа,然назад被babel
компилировать
React.createElement(type, [props], [...children])
type
ReactFragment
[props]
:верно象,из атрибута в классе dom,Компоненты вprops[...children]
:другойизпараметр,Будет отсортировано соответствующим образомcloneElement
:Клонировать и объединитьвозвращатьсяодининдивидуальныйновыйизReact
элемент,
React.createElement(type, [props], [...children])
React.cloneElement()
几乎等同В:
<element.type {...element.props} {...props}>
{children}
</element.type>
createContext
встречасоздаватьодининдивидуальныйОбъект контекста
,
Provider
изvalue
来передачаценитьConsumer
приниматьvalue
Children
: поставлятьиметь дело сthis.props.children
不透明данные结构из实использовать程序。
Children.map
:Траверс,ивозвращатьсяодининдивидуальныймножество
const Child = ({children}) => {
const res = React.Children.map(children, (item) => item)
console.log(res)
return res
}
Children.forEach
:иChildren.map
добрый似,другойиздаChildren.forEach
и不встречавозвращатьсяценить,Вместо этого оставайтесь на этапе обхода
Children.count
:возвращатьсяChild
изобщийиндивидуальныйчисло,Равно количеству раз, когда будет вызван обратный вызов, переданный в mapилиforEach.
Children.only
:проверятьChildда否只иметьодининдивидуальныйэлемент,
Children.toArray
:к«Плоский массив»изформавозвращатьсяchildren
不透明данные结构,Каждому отдельному дочернему элементу назначается ключ.
createRef
:создаватьодининдивидуальныйссылочный объект
,Получить информацию об узлах
isValidElement
:использовать Впроверятьда否даРеагировать элементы
,
true
,false
ПроверятьReact
изномер версии
React
из жизненный цикл В основном включают две отдельные версии большего размера соответственно
v16.0
впередv16.4
дваиндивидуальный Версияизжизненный цикл。
общий共分для«Четыре этапа»:
существует фаза инициализации, будет использоваться constructor()
этотиндивидуальный构造функция,нравиться:
constructor(props) {
super(props);
}
super
изделатьиспользоватьconstructor()
),props
вводить вподкомпонент,дляподкомпонентчитатьthis.state
изисходное содержаниеcomponentWillMount
:существовать组куски挂载приезжатьDOMвперед调использоватьthis.setState
不встречапричина组кускииз重новыйрендеринг,也Может把写существоватьэтот边из Упомянутый контентconstructor()
,Так что существующих проектов очень мало.render
: рендерингprops
иstate
изменять(无论ценитьда否иметь变化,два ВОЗиз重передачаи重赋ценить,都Можетпричина组куски重новыйrender
),повторю рендерингрендеринг
。return
:«Это обязательно,Является индивидуальным элементом React",Не несет ответственности за фактическую работу рендеринга компонента.,Сам React использует этот элемент для вывода DOM.render
да«Чистая функция»,не может быть выполненоthis.setState
。componentDidMount
:组куски挂载приезжатьDOMназад调использоватьcomponentWillReceiveProps(nextProps)
:调использовать Вprops
причинаиз组кускивозобновлять过程серединаnextProps
:父组куски传Давать当вперед组кускиновыйизprops
nextProps
иthis.props
для выявления повторных передачprops
да否изменять(原потому что:不能保证父组куски重传изpropsиметь变化)props
изменять Сразувстреча,вызвать звонокshouldComponentUpdate(nextProps, nextState)
:«Для оптимизации производительности»nextProps
:当вперед组кускиизthis.props
nextState
:当вперед组кускиизthis.state
nextProps
иnextState
,Определить, необходимо ли текущему компоненту продолжать выполнение процесса возобновления.false
:выражать停止возобновлять,Используется для уменьшения количества ненужных компонентов рендеринга.,Оптимизация производительностиtrue
:Продолжить выполнениевозобновлятьcomponentWillReceiveProps()
середина执行Понятноthis.setState
,возобновлять Понятноstate
,носуществоватьrender
вперед(нравитьсяshouldComponentUpdate,componentWillUpdate),this.state
все еще「ориентированныйвозобновлятьвпередизstate」,В противном случае сравнение nextState с текущим компонентом this.stateiz всегда будет истинным.componentWillUpdate(nextProps, nextState)
:组кускивозобновлятьвперед调использоватьrender
методвперед执行render
:重новыйрендерингcomponentDidUpdate(prevProps, prevState)
:组кускивозобновлятьназад被调использоватьprevProps
:组кускивозобновлятьвпередизprops
prevState
:组кускивозобновлятьвпередизstate
componentWillUnmount
:组куски被卸载вперед调использовать
существуют, могу провести здесь кое-какие работы по уборке.,Например, явно используйте таймер в компоненте,ПрозрачныйcomponentDidMount
середина手动создаватьизDOMэлемент等,Чтобы избежать утечек памяти
и v16.0
изжизненный цикл сравнения
getXX
)getDerivedStateFromProps
getSnapshotBeforeUpdate
componmentWillXX
)componentWillMount
、componentWillReceiveProps
、componentWillUpdate
getDerivedStateFromProps(prevProps, prevState)
:组куски«При создании ивозобновлять»调использоватьизметод
prevProps
:组кускивозобновлятьвпередизpropsprevState
:组кускивозобновлятьвпередизstate❝существовать
React v16.3
середина,существоватьсоздаватьивозобновлятьчас,Эту отдельную функцию можно вызвать только в том случае, если она запускается родительским компонентом.,существоватьReact v16.4
изменятьдля无论даMounting
还даUpdating
,Все будут вызваны. ❞
даодининдивидуальный«Статическая функция»,也Сразудаэтотиндивидуальныйфункция不能проходитьthis
Посетилclass
изсвойство。
❝если
props
входящийизсодержание不需хотеть影响приезжатьтыизstate
,那么Сразу需хотетьвозвращатьсяодининдивидуальныйnull
,этотиндивидуальный「возвращаться обязательно.」,Поэтому попробуйте записать это в конец функции. ❞
существовать组кускисоздаватьчасивозобновлятьчасиз«Вызывается перед методом рендеринга»,должно
null
Приходи или нетвозобновлять任чтосодержаниеgetSnapshotBeforeUpdate(prevProps,prevState)
:Updating
часизфункция,「существоватьrender之назад调использовать」
prevProps
:组кускивозобновлятьвпередизpropsprevState
:组кускивозобновлятьвпередизstateумею читать,Но когда DOMиз нельзя использовать,существовать组куски Можетсуществовать可能更изменять До从DOM捕获один些информация(Напримерположение прокрутки)
「возвращатьсяиз任что指都Воляделатьдляпараметрпередача ДаватьcomponentDidUpdate()
」
существуют версия 17.0из версии, официально упразднена
componentWillMount
、componentWillReceiveProps
、componentWillUpdate
react-hooks
даReact 16.8
изпродукт,«Придание жизненного цикла функциональным компонентам»。
useState
:определение变量,Может理解для他дадобрый Компоненты вthis.state
использовать:
const [state, setState] = useState(initialState);
state
:глазиздапоставлять Давать Пользовательский интерфейс, как представление для рендеринга из источника данныхsetState
:изменять变 state
изфункция,Может理解дляthis.setState
initialState
:初始默认ценить❝
useState
иметь点добрый似ВPureComponent
,встречаруководитьодининдивидуальный Сравнивать浅из Сравнивать,в Когда объект события передается напрямую, он не возобновляется. ❞
useEffect
:副делатьиспользовать,Вы можете понять, что for — это компонент класса, изжизненный цикл.,Это также наш наиболее часто используемый крючок.
❝副делатьиспользовать(
Side Effect
):да指function
Сама операция не имеет ничего общего со значением, например запрос данных, изменение глобальных переменных, печать, сбор данных, настройка подписок и изменения вручную.React
Компоненты вDOM
Все это побочные эффекты ❞
useEffect
不设立второйиндивидуальныйпараметрчас,независимо от ситуации,будет выполненuseEffect
извторойиндивидуальныйценитьuseContext
:上Вниз文,добрый似ВContext
:其本意Сразуда设置全局共享данные,«Разрешить всем компонентам обмениваться данными на разных уровнях»
useContent
изпараметродин般да由createContext
изсоздавать,проходить CountContext.Provider
Комплектация компонентов, возможность подачи useContext
Получите соответствующее значение
useReducer
:этодобрый似Вredux
Функцияизapi
const [state, dispatch] = useReducer(reducer, initialArg, init);
state
:возобновлятьназадизstate
ценитьdispatch
:Может理解дляиuseState
изsetState
один样из Эффектreducer
:Может理解дляredux
изreducer
initialArg
:初始ценитьinit
:Ленивая инициализацияuseMemo
:иmemo
из理念上差不много,都да判断да否满足«Текущие ограничения»来决定да否执行callback
функция,иuseMemo
извторойиндивидуальныйпараметрдаодининдивидуальный"Множество",использовать этот индивидуальный массив, чтобы определить, следует ли выполнять функцию обратного вызова
❝当одининдивидуальный父组кускисередина调использовать Понятноодининдивидуальныйподкомпонентизкогда,父组кускииз
state
изменять,Приведёт к возобновлению родительского компонента.,иподкомпонент虽然没иметьизменять,но也встречаруководитьвозобновлять。 ❞
Пока родительский компонент не будет возобновлен,「无论иметь没иметьверноподкомпонентруководить操делать,подкомпонент都встречаруководитьвозобновлять」,useMemo
Сразудадля Понятно防止этот点и出сейчасиз。
useCallback
иuseMemo
极其добрый似,Единственная разница в том,
useMemo
возвращатьсяиздафункция运行изрезультат,useCallback
возвращатьсяизда"функция"React.memo
,В противном случае производительность не только не улучшится, но и может ухудшиться.useRef
: Может获取当впередэлементиз所иметьсвойство,ивозвращатьсяодининдивидуальныйпеременнаяизссылочный объект
,иэтотиндивидуальныйверно象只иметьтекущий атрибут
,Можно установитьinitialValue
Реагировать элементы
изсвойствоценитьuseImperativeHandle
:Можетпозволятьтысуществоватьиспользовать ref
При настройке значения экземпляра, доступного родительскому компоненту
useImperativeHandle(ref, createHandle, [deps])
ref
:useRef
所создаватьизrefcreateHandle
:иметь дело сизфункция,возвращатьсяценитьделатьдля暴露Давать父组кускииз ref
объект.deps
:Зависимости,Зависимости更изменять形成новыйиз ref
объект.❝
useImperativeHandle
иforwardRef
配合использовать ❞
function FancyInput(props, ref) {
const inputRef = useRef();
useImperativeHandle(ref, () => ({
focus: () => {
inputRef.current.focus();
}
}));
return <input ref={inputRef} ... />;
}
FancyInput = forwardRef(FancyInput);
существовать父组кускисередина,Можетрендеринг<FancyInput ref={inputRef} />
и Можетпроходить父组кускиизinputRef
верноподкомпонентсерединаизinput
руководитьиметь дело с。inputRef.current.focus()
useLayoutEffect
: иuseEffect
基本один致,Когда в разных местах,**useLayoutEffect
да同步**
хотеть УведомлениеиздаuseLayoutEffect
существовать «После обновления DOM, до отрисовки браузером»,этот样Делатьиз好处да Может更加方便из修изменять ДОМ,возьми DOM информация,этот样浏览器只встреча绘制один次,так«useLayoutEf существует, выполняется до useEffect»
в случае useEffect
изразговаривать ,useEffect
"После выполнения существующего вида чертежа браузера,Если существует изменение DOM в это время,Это может привести к повторной перекомпоновке и перерисовке браузера».。
кромеuseLayoutEffect
из callback
серединакод执行встреча«Блокировать рисование в браузере»
useDebugValue
:可использовать Всуществовать React
Настройка отображения в инструментах разработчика hook
из тега
useSyncExternalStore
:даодининдивидуальный推荐использовать Вчитатьи订阅外部данные源из hook
,Его метод и селективность hydration
Совместимость с разделением времени и другими функциями параллельного рендеринга.
const state = useSyncExternalStore(
subscribe,
getSnapshot[, getServerSnapshot]
)
subscribe
: 订阅функция,Используется для регистрации функции обратного вызова,«Вызывается при изменении сохраненного значения»。также, useSyncExternalStore
будет проводиться по памяти из getSnapshot
来判别данныеда否изменять,если произойдут изменения,那么встреча«Принудительное обновление данных»。getSnapshot
: получается текущее сохраненное значение из функции. Должен появиться кэш из значения. если getSnapshot
连续много次调использовать,тогда должно получиться то же самое по точному значению,Если в середине нет сохраненного значения.getServerSnapshot
:возвращаться Сервер(hydration模式Вниз)рендеринг期间использоватьизжить储ценитьизфункцияuseTransition
:
«Переходная задача»существоватьодин些场景середина,Например: поле ввода, переключатель вкладок, кнопка и т. д.,Эти任务需хотеть视图上«Ответить немедленно»,Эти задачи можно вызвать для мгновенного возобновления задач.
Но иногда,возобновить Задача не такая уж и срочная,или Например, вам нужно запросить данные и т.д.,В результате новый статус невозможно сразу возобновить.,需хотетьиспользоватьодининдивидуальныйloading...
изждатьсостояние,Такие задачи являются переборами
const [isPending, startTransition] = useTransition();
isPending
:«Переходное состояние из флага»,fortrue — это состояние ожиданияstartTransition
:Может Волявиз Задача становится переходной задачейuseDeferredValue
:приниматьодининдивидуальныйценить,ивозвращаться该ценитьиз«Новая копия»,Эта копия будет"откладывать"к более срочномувозобновлять之назад。
Если текущий рендеринг является индивидуальной чрезвычайной ситуацией, возобновить результат,Например, пользовательский ввод,React
Воля「возвращаться Доизценить」,然назад「существоватьсрочныйрендеринг完成назадрендерингновыйизценить」。
То естьuseDeferredValue
Можетпозволять«Вывод государственного лага»。
const deferredValue = useDeferredValue(value);
value
:переменнаяизценить,Например, useState создает значениеdeferredValue
: Статус задержки「useTransitionиuseDeferredValueДелатьиндивидуальныйверно比」
useDeferredValue
и useTransition
То же, это все переходные задачиuseTransition
Даватьиздаодининдивидуальный"состояние",иuseDeferredValue
Даватьиздаодининдивидуальный"ценить"useInsertionEffect
:и useLayoutEffect
То же самое, но все это существует DOM 突变До«Синхронизированный триггер»
существуют исполнительный лист useInsertionEffect
> useLayoutEffect
> useEffect
❝
seInsertionEffect
должно быть ограниченоcss-in-js
Используется авторами библиотеки. Расставьте приоритеты в использованииuseEffect
илиuseLayoutEffect
заменить. ❞
useId
: даодининдивидуальный«Используется для создания уникального идентификатора на сервере и клиенте, стабильно и стабильно» из同час避免hydration
нет совпаденийиз hook。
createPortal
:существоватьPortal
серединапоставлять Понятноодин种Воляребенокузелрендерингприезжать DOM узелсерединаиз Способ,«Этот узел хранится вне компонента DOM из иерархии»。
То есть createPortal
Может把当вперед组кускиилиelement
элементизребенокузел,рендеринг в другие места за пределами компонента.
Приходите и посмотритеcreatePortal(child, container)
из Вход:
flushSync
:Может«Поместите функцию обратного вызова в задачу,Поставьте этому более высокий приоритет».,适использовать В«Принудительное обновление, гарантируя, что DOM будет обновлен немедленно»
onClick={() => {
this.setState({ number: 1 })
this.setState({ number: 2 })
this.setState({ number: 3 })
}}
потому чтодляthis.setState
встречаруководить«Пакетное обновление»,Таким образом, напечатанное из равно 3
onClick={() => {
this.setState({ number: 1 })
ReactDOM.flushSync(()=>{
this.setState({ number: 2 })
})
this.setState({ number: 3 })
}}
发сейчасflushSync
встреча优先执行,Принудительное обновление,Таким образом, это изменит числовое значение для2,Затем 1и3существовать обновляется пакетно.,возобновлятьдля3
render
:этотиндивидуальныйданассуществоватьReact-Dom
середина最常использоватьизApi,использовать ВрендерингодининдивидуальныйРеагировать элементы
ReactDOM.render(
< App / >,
document.getElementById('app')
)
существоватьReact v18
середина,render
функция已经被createRoot
заменен на。
createRoot
встреча控制тывходящийизконтейнерузелизсодержание。当调использовать render
час,「виз任чтосейчасиметь DOM элементы будут заменены"。назад面из调использоватьиспользовать React
из DOM diffing
алгоритмруководитьиметь效возобновлять。
и createRoot
«Не изменяйте узел контейнера»(只修изменятьконтейнеризребенокузел)。Можетсуществовать不覆盖сейчасиметьребенокузелиз情况Вниз Воля组куски插入сейчасиметь DOM узел.
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(
<StrictMode>
<Main />
</StrictMode>
);
unmountComponentAtNode
:从 DOM середина卸载组куски,встреча Воля其事кускииметь дело с器(event handlers
)и state
Очистите их все вместе. Если в указанном контейнере нет соответствующего смонтированного компонента, эта отдельная функция ничего не сделает.
unmountComponentAtNode
такой жесуществоватьReact 18
середина被替代Понятно,替换成ПонятноcreateRoot
серединаизunmount()
метод
const root = createRoot(container);
root.render(element);
root.unmount()
findDOMNode
:использовать В访问组кускиDOMэлементузел(план действий в чрезвычайной ситуации),Официально рекомендуется использовать ссылку
unstable_batchedUpdates
:可использовать В«Пакетное обновление вручную»state,Может指定многоиндивидуальныйsetState合идляодининдивидуальныйвозобновлятьпросить
«Поделиться – это отношение»。
«Весь текст окончен,Теперь, когда Видеть здесь,Если ты чувствуешь себя хорошо,Просто нажмитеиндивидуальныйхвалитьи“существоватьсмотреть”Бар。」