#javascript #reactjs
Вопрос:
Когда я изучал крючки react, я увидел пример функции useState, выполненной из ванильного javascript.
function useState(initVal) {
let _val = initVal
const state = _val
const setState = newVal => {
_val = newVal
}
return [state, setState]
}
const [count, setCount] = useState(1)
console.log(count) // 1
setCount(2)
console.log(count) // 1
Хотя я объявил состояние переменной, при вызове функции setState с помощью newValue счетчик не меняется.
Однако, когда состояние изменяет переменную на функцию, как показано ниже,
function useState(initVal) {
let _val = initVal
const state = () => _val
const setState = newVal => {
_val = newVal
}
return [state, setState]
}
const [count, setCount] = useState(1)
console.log(count()) // 1
setCount(2)
console.log(count()) // 2
счет начинает меняться.
Происходит ли это потому, что всякий раз, когда функция count вызывает, она ссылается на измененное значение _val функцией setState с помощью закрытия? и как я могу объяснить, как работают крючки react с использованием закрытия в javascript?
Комментарии:
1. вы просмотрели ответы ниже?
Ответ №1:
При деструкции вы получаете новые, отличные переменные с копиями данных.
// simple explanation
const list = ['dog'];
const [animal] = list;
console.info(animal); // dog
// change the original
list[0] = 'cat';
// output
console.info(list[0], animal); // cat, dog
Даже если вы проведете рефакторинг, как показано ниже, для правильного использования let
и обновления, вы не получите исходное значение, так как на него нет ссылки.
function useState(initVal) {
let state = initVal
const setState = newVal => {
state = newVal;
}
return [state, setState];
}
const [count, setCount] = useState(1);
console.log(count); // 1
setCount(2);
console.log(count); // 1
// simple explanation
const list = ['dog'];
const [animal] = list;
console.info(animal);;
list[0] = 'cat';
console.info(list[0], animal);
Ответ №2:
Хотя я объявил состояние переменной
На самом деле, ты этого не сделал. Вы объявили это как константу.
Первый возвращает значение переменной. Просто и понятно. Так уж случилось 1
. Значение скопировано, вы не можете его изменить. (Очевидно, вы можете изменить значение счетчика, но вы не можете изменить 1
).
Второй возвращает функцию. Эта функция образует замыкание _val
. _val
не оценивается до count()
тех пор, пока не будет вызван. Каждый раз, когда он вызывается, он получает значение _val
и возвращает его.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
Ответ №3:
Потому что вы снова привязываете его к этой линии
const state = _val
Состояние становится постоянной, замороженной с начальным значением
return [_val, setState]
Измените его на этот, и вы получите то, что ожидали