Привет ~ Уважаемый зритель, все, все ~ Недавно несут ответственность за реконструирование внутренней системы, поскольку это внутренняя система, конечно, вы можете использовать ее и решить после анализа спроса.React
Последняя версия Refactowed. Так как это последняя версия, это, конечно, использоватьHooks
развитый. Процесс разработки не гладкий, но можно считать, что наступило много ям и вылезло снова.После подведения итогов у меня есть эта статья~
Примечание ~ Эта статья представляет собой обсуждение, связанное с практикой, если это неясно.Hooks
одноклассники, может эта статья вам не подходит. При этом в процессе практики я использовал рядReact
Не рекомендованный официалом режим, эта статья в основном для обсуждения этого, надеюсь вы сможете написать модель на основеHooks
изReact
Когда код полезен - ниже текст:
вызов в цикле, условныйHook
React
официальный сайт находится по адресуHook
правилоВ одном разделе есть такой отрывок:
Не вызывайте циклы, условные операторы или вложенные функции.
Hook
, убедитесь, что всегда в вашемReact
Их вызывает функция верхнего уровня.
Однако я часто нарушаю этот принцип (во избежание проблем) в реальном процессе разработки. Сначала поймите, почему официально не рекомендуется вызывать циклы, условия или вложенные функции.Hook
. внутри функционального компонентаHook
Он регистрируется на основе связанного списка, то есть последовательности с фиксированным порядком, следующим образом:
Hook1 ⟶️ Hook2 ⟶️ Hook3 ...⟶️... HookN
ПредположениеHook2
в состоянии суда, один разcondition
Изменить, изменится порядок выполнения:
if (condition) {
useHook2();
}
执行顺序变为:Hook1 ⟶️ Hook3 ...⟶️... HookN
порядок сместится, что приведет кReact
Внутренняя ошибка.
После того, как у вас будет общее представление о принципе кода, вы сможете понять, почему официал не рекомендует использовать его в циклах или условиях.Hook
. Однако первопричиной этой проблемы является изменение порядка, что приводит к ошибкам. Что, если бы мы могли гарантировать порядок исполнения? Например: в локальной среде разработки вам нужно добавить некоторый код отладки, но не хотите, чтобы соответствующий код отображался в сети, обычно мы напишем:
if (process.env.NODE_ENV === 'development') {
//do sth...
}
Когда официальный код будет выпущен, этот код отладки будет правильно удален инструментом упаковки. Поскольку переменные среды фиксированы (в основном неизменны в той же среде), даже еслиHook
В условном суждении, в функцииHook
Порядок фиксированный и использовать не проблема:
function Test() {
let test;
let setTest;
if (process.env.NODE_ENV === 'development') {
[test, setTest] = useState(1); // eslint-disable-line
}
// 添加 eslint-disable-line,是因为 ESLint 在开发环境中会检测 `Hook` 是否在合理的上下文之中(即不在条件判断或循环之中),不然会报错并停止渲染
return (
<div>
<p>{test}</p>
<button onClick={() => setTest(test + 1)}>click</button>
</div>
)
}
То же самое верно в условиях цикла (до тех пор, пока число петлей исправлено, проблем нет). Просто будь увереннымHook
ПоследовательностьПока вы точно знаете, что делаете~
Обман зависимости против точной зависимости
Будь тоReact
документация по-прежнемуHooks
Связанные статьи, многие предполагают, что мыHook
Массив зависимостей честно, заполнить правдивоHook
переменные внутри, чтобы избежать ошибок:
useEffect(() => {
reportToService(userName, userId, ...)
}, [userName, userId, ...])
Однако это не должно быть жесткой догмой — представьте себе сценарий приведенного выше кода, представляющего собой часть логики, которая передает данные на сервер. Если такая информация, как имя пользователя, должна измениться после выхода пользователя из системы, тоuseEffect
Он будет выполнен повторно.Если предположить, что это фрагмент кода, который подсчитывает PV, возникает проблема повторяющейся статистики. таким образом,Пока вы точно знаете, что делаете, зависимости могут быть фактически заполнены в соответствии с реальной ситуацией, нет необходимости форсировать все используемые переменные.
И точная зависимостьReact
Следует сказать, что воплощение неизменяемых данных в определенной степени позволяет избежать неправильного заполнения зависимостей, рассмотрим следующий пример:
function Test() {
const [test, setTest] = useState({
key1: 1,
key2: 2
});
useEffect(() => {
console.log(test.key2);
}, [test]);
return (
<div>
<p>{test.key1}</p>
<button onClick={() => setTest(test => {
return {
...test,
key1: test.key1 + 1
}
})}>
click
</button>
</div>
)
}
Приведенный выше пример работает нормально,ESLint
Он также не сообщит об ошибке. Однако, когда мы продолжаем нажимать кнопку,useEffect
будет продолжать выполняться, распечатываяtest.key2
ценность . Это связано с тем, что после нажатия кнопкиtest
это новый объект, поэтомуuseEffect
зависимости изменились, поэтому они постоянно выполняются. Но это бессмысленно, мы действительно хотим отслеживатьtest.key2
, поэтому зависимые элементы должны быть заполнены точно так же, какtest.key2
, после модификацииuseEffect
только вtest.key2
Это будет реализовано только после изменений.
Точные зависимости — небольшая деталь, но часто приводят к повторному выполнениюHook
, при обнаружении подобных проблем вы можете сначала проверить переменные, которые зависят от неправильного.
Hook
если неsetState
, а не функция жизненного цикла
Так как давно не писалReact
, поэтому в начале напишитеHook
еще с тяжелымclass
Цвет, в основном можно сказать, что толькоclass
"перевести наfunction
Вот и все.
В использованииuseState
, бросьте внутрь большой предмет, имитируя предыдущийstate
, но это типичный антипаттерн. Хотя необходима инкапсуляция данных, например, интеграция пользовательских данных вuserInfo
объект, но будет иметь все содержимое, как и раньшеclass
то же самое, положить вstate
, нежелательно и приведет к этомуHook
Это становится довольно тяжелым, и это не способствует логическому повторному использованию, что нарушаетHook
Первоначальная цель.
Hook
нетsetState
Это легче понять, ноHook
Это не очень хорошая практика, если это не функция жизненного цикла. Например, мы частоcomponentWillUnmount
Раскрутить таймеры, отменить привязку событий и т. д.:
componentWillUnmount() {
clearTimeout(timer);
removeEventListener('click', handler);
...
}
Однако вHook
, записать все операции, такие как освобождение таймеров, отвязка событий и т. д., в одинuseEffect
Это не лучшая практика. Из вышеизложенного мы узнали, что мы должны попытаться добиться точных зависимостей и избежать ненужных накладных расходов. С точки зрения логического повторного использования более удобно повторное использование, если код разделен по функциям. Поэтому мы должны написать:
useEffect(() => {
const timer = setTimeout(() => {
...
});
return () => {
clearTimeout(timer);
}
}, []);
useEffect(() => {
element.addEventListener('click', handler);
return () => {
element.removeEventListener('click', handler);
}
}, []);
...
class
В каждом из них есть только одна функция жизненного цикла, иfunction
в соответствующемHooks
Может быть несколько разбиений ~ для ясности кода и логического повторного использования.
Небольшой разговор о производительности
Производительность — большая тема, вHooks
Вопросы, связанные с производительностью, в основном могут быть написаны в отдельной статье~ Потому чтоReact
После непеременных данных, поэтому их обновление является пакетным:
В качестве наилучшей практики мы должны использоватьuseMemo
,useCallback
И так далее до кэширования, чтобы избежать повторной генерации переменных и привести к бессмысленному пересчету Virtual DOM. Но я, любитель "навести беспорядок", ради шишки придумал небольшой антипаттерн - наше приложение может быть не настолько большим, чтобы производительность нужно было учитывать в полной мере.
использоватьHook
При разработке, чтобы оставить переменные неизменными, нужно использовать множествоuseMemo
,useCallback
Такие хуки, каждая переменная и метод должны быть инкапсулированы этими хуками для максимальной производительности. Иногда возникает ощущение, что постоянно пишу шаблонный код, вспоминаяRedux
Страх господства?Hook
Немного этого чувства тоже.
Чтобы было ясно,производительность имеет значение. Но также имейте в виду, что для обычных интерфейсных приложений это будет выполнено в течение 1 мс или 10 мс.diff
, это действительно не имеет смысла. Как показывает опыт, работа бюджетных мобильных телефонов в пределах миллиона уровней не вызовет явных задержек. ОднакоDOM
Это довольно медленно, около 6000 младших машинDOM
При повторном рендеринге это приведет к очень очевидным заиканиям. Таким образом, с личной точки зрения похвально поддерживать высокую производительность приложения, но не рекомендуется добиваться максимальной производительности в малых и средних приложениях, и неплохо было бы оптимизировать ее, когда производительность снижается. встречается узкое место.
резюме
Это все для этой статьи! Это то, что я использую в своем проектеHook
Немного подумав после разработки, ведь «лучше не иметь книг, чем верить в книги», а новые технологии можно освоить только на практике.
Вышеизложенное является небольшим личным мнением, спасибо всем зрителям за то, что увидели это. Легче сказать, чем сделать, надеюсь, эта статья будет вам полезна~ Спасибо!