**Lodash
Для работы со сложными структурами данных вам может потребоваться использовать такие методы, как сопоставление вложенных данных (маппинг, mapping), использование рекурсивных компонентов для визуализации данных с несколькими уровнями вложенности и оптимизация производительности с помощью таких методов, как React.memo
. Также может быть полезно использовать библиотеки, такие как lodash
, для управления и преобразования сложных структур данных. Например, функция debounce
из библиотеки lodash
, полезна для сокращения количества API запросов.
Очевидно, что в React существует множество способов обработки сложных структур данных. Вот несколько сценариев, в которых вам, возможно, придется более осторожно подходить к обработке и представлению данных.
- Вложенные структуры данных, такие как дерево или граф.
- Большие наборы данных, которые необходимо отображать и обрабатывать в виде таблицы или списка.
- Структуры данных со многими уровнями вложенности, например, объект JSON с несколькими уровнями вложенных объектов и массивов.
- Структуры данных, которые постоянно меняются, например, данные в режиме реального времени из прямой трансляции или подключения через веб-сокет.
Lo-Dash — это полноценная замена* для Underscore.js. Lo-dash имеет более высокую производительность, избавлен от некоторых багов underscore и даёт некоторые новые возможности.
- Поддержка AMD-загрузчиков (RequireJS, curl.js, etc.)
_.clone
поддерживает “глубокое” клонирование_.forEach
поддерживает текучий интерфейс и остановку итерирования_.forIn
для итерирования по собственным и унаследованным свойствам объектов_.forOwn
для итерирования только по собственным свойствам объекта_.isPlainObject
проверяет, было ли значение создано с помощью конструктораObject
_.lateBind
для позднего связывания_.merge
— “глубокий” аналог_.extend
_.partial
для карринга без связыванияthis
_.pick
и_.omit
принимают аргументыcallback
иthisArg
_.template
использует sourceURLs для более простой отладки_.contains
,_.size
,_.toArray
, и т.д.… принимают и строки тоже
Поддержка индивидуальных сборок позволяет легко создавать облегчённые версии Lo-Dash
, содержащие только необходимые вам методы. Также Lo-Dash
поддерживает за вас зависимости методов и псевдонимы.
- Сборка, содержащая всё необходимое для работы Backbone, может быть создана с модификатором
backbone
.
lodash backbone
-
Content Security Policy сборка.
lodash csp
-
Сборка для старых браузеров без поддержки ES5.
lodash legacy
-
Сборки для мобильных платформ, без баг-фиксов для IE < 9 и компиляции методов.
lodash mobile
-
Strict-сборки, с использованием strict mode для
_.bindAll
,_.defaults
, and_.extend
.lodash strict
-
Underscore-сборка, для тех, кто уже используется Underscore в своих проектах.
lodash underscore
-
Бенчмарки + еще бенчмарки на jsPerf.com (в моём случае дают ускорение в 1.75 раз)
Подробнее: Lo-Dash , Ссылка на методы Lodash, Хватит импортировать JavaScript-пакеты целиком
**Debounce
Результатом декоратора debounce(f, ms)
должна быть обёртка, которая передаёт вызов f
не более одного раза в ms
миллисекунд. Другими словами, когда мы вызываем debounce
, это гарантирует, что все остальные вызовы будут игнорироваться в течение ms
.
let f = debounce(alert, 1000)
f(1) // выполняется немедленно
f(2) // проигнорирован
setTimeout(() => f(3), 100) // проигнорирован (прошло только 100 мс)
setTimeout(() => f(4), 1100) // выполняется
setTimeout(() => f(5), 1500) // проигнорирован (прошло только 400 мс от последнего вызова)
Пример написания кастомного хука debounce
на React:
import { useState, useEffect } from "react"
const useDebounce = (value, delay) => {
const [debouncedValue, setDebouncedValue] = useState(value)
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedValue(value)
}, delay)
return () => {
clearTimeout(timerId)
}
}, [value, delay])
return debouncedValue
}
// Пример использования
const MyComponent = () => {
const [inputValue, setInputValue] = useState("")
const debouncedInputValue = useDebounce(inputValue, 500)
useEffect(() => {
// Выполнять действия при изменении задержанного значения
console.log("Debounced value:", debouncedInputValue)
}, [debouncedInputValue])
const handleChange = (event) => {
setInputValue(event.target.value)
}
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
</div>
)
}
На практике debounce
полезен для функций, которые получают/обновляют данные, и мы знаем, что повторный вызов в течение короткого промежутка времени не даст ничего нового. Так что лучше не тратить на него ресурсы.
Подробнее: debounce
**Throttle
Декоратор throttle(f, ms)
, возвращает обёртку, передавая вызов в f
не более одного раза в ms
миллисекунд. Те вызовы, которые попадают в период «торможения», игнорируются.
function f(a) {
console.log(a)
}
// f1000 передаёт вызовы f максимум раз в 1000 мс
let f1000 = throttle(f, 1000)
f1000(1) // показывает 1
f1000(2) // (ограничение, 1000 мс ещё нет)
f1000(3) // (ограничение, 1000 мс ещё нет)
// когда 1000 мс истекли ...
// ...выводим 3, промежуточное значение 2 было проигнорировано
Отличие от debounce
– если проигнорированный вызов является последним во время «задержки», то он выполняется в конце.
Пример написания кастомного хука throttle
на React:
import { useState, useEffect } from "react"
const useThrottle = (value, delay) => {
const [throttledValue, setThrottledValue] = useState(value)
const [lastExecTime, setLastExecTime] = useState(Date.now())
useEffect(() => {
const timerId = setTimeout(() => {
const now = Date.now()
const timeSinceLastExec = now - lastExecTime
if (timeSinceLastExec >= delay) {
setThrottledValue(value)
setLastExecTime(now)
}
}, delay)
return () => {
clearTimeout(timerId)
}
}, [value, delay, lastExecTime])
return throttledValue
}
// Пример использования
const MyComponent = () => {
const [inputValue, setInputValue] = useState("")
const throttledInputValue = useThrottle(inputValue, 500)
useEffect(() => {
// Выполнять действия при изменении ограниченного значения
console.log("Throttled value:", throttledInputValue)
}, [throttledInputValue])
const handleChange = (event) => {
setInputValue(event.target.value)
}
return (
<div>
<input type="text" value={inputValue} onChange={handleChange} />
</div>
)
}
Обычно используется для ограничения частоты выполнения определенных действий или обработки событий в React-компонентах. Вот несколько распространенных примеров использования useThrottle
:
- Обработка событий ввода
- Оптимизация обновлений компонента
- Отправка запросов к API