Почему функция useState, созданная на javascript, не работает, когда состояние является переменным?

#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]
 

Измените его на этот, и вы получите то, что ожидали