Я пытаюсь написать пользовательский хук React, который возвращает функции, которые поддерживают равенство ссылок при каждом вызове хука. Это означает, что точно одна и та же функция возвращается из ловушки каждый раз, так что сравнение их с ===
возвращает true
.
У меня сложилось впечатление, что useCallback
hook это был способ сделать sh что:
function useCorrectCallback() {
const [count, setCount] = useState(0)
let increment = () => setCount(c => c + 1)
let memoized = useCallback(increment, [])
return {
count,
increment: memoized
}
}
Поэтому, когда вызывается этот хук, я считаю, что свойство increment
возвращаемого значения должно каждый раз быть одной и той же функцией. Это должно быть значение встроенной функции при первом запуске ловушки, и не должно изменяться при последующих выполнениях ловушки, потому что я не указал никаких зависимостей для useCallback
с []
.
Но это не так что, кажется, случается! Я написал тестовый проект , чтобы продемонстрировать эту проблему. Вот суть этого теста :
function validateFunctionEquality(hookResult) {
// Store the last result of running the hook
let stored = { ...hookResult }
// Force a re-render to run the hook again
expect(hookResult.count).toEqual(0)
act(hookResult.increment)
expect(hookResult.count).toEqual(1)
// Compare the previous results to the current results
expect(hookResult.constant).toEqual(stored.constant)
expect(hookResult.increment).toEqual(stored.increment)
}
Просто для проверки точности моих тестов я также написал хук, который просто использует объект с глобальной областью действия для поддержания «памяти» вместо пытаясь попросить React сделать это с useCallback
. Этот хук проходит тесты:
let memoryHack = {}
function useMemoryHack() {
const [count, setCount] = useState(0)
let increment = () => setCount(c => c + 1)
memoryHack.increment = memoryHack.increment || increment
return {
count,
increment: memoryHack.increment
}
}
Я неправильно использую useCallback
? Почему useCorrectCallback
возвращает другую функцию в свойстве increment
при последующих выполнениях?