Как setColor() ссылается на самую последнюю переменную цвета?

export default function App() {
  let [color, setColor] = useState("red");

  useEffect(() => {
    setColor("blue");
    setTimeout(() => {
      console.info(color);
      setColor("purple");
    }, 1000);
  }, []);

  function revealColor() {
    console.info(color);
  }
  return <button onClick = {revealColor}>Click after 1 second to reveal color</button>
}

Песочница

После этого предыдущего вопроса я понимаю, что обратный вызов setTimeout ссылается на первую переменную color (красная). Каким-то образом его setColor удается изменить самую последнюю переменную color (о чем свидетельствует нажатие кнопки, которая регистрирует «фиолетовый»). Как это так? Я думал, что setColor будет так же ссылаться на старую переменную setColor.

P.S. под «старым» я имею в виду тот факт, что setColor("blue"); повторно выполняет весь компонент, который возвращает новую color переменную/функцию.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это потому, что вы не включили color в массив зависимостей useEffect. Из-за этого useEffect не знает, что color изменился. Если вы включите его в массив зависимостей, то useEffect будет срабатывать при каждом изменении color. Таким образом, вы можете увидеть blue, когда вы входите в систему.

useEffect(() => {
    setColor("blue");
    setTimeout(() => {
      console.info(color);
      setColor("purple");
    }, 1000);
  }, [color]); // <- dependency array

Ответ принят как подходящий

setColor — это функция, которая изменяет color в состоянии. Он не изменяет напрямую переменную color.

Каждый раз, когда состояние изменяется, функция App запускается повторно.

Поэтому, когда он запускается в первый раз, он вызывает useState("red"), обнаруживает, что существующего состояния нет, устанавливает состояние в "red", а затем присваивает состояние ("red") color. DOM обновляется с результатом.

setColor("blue"); изменяет состояние на "blue", что приводит к повторному запуску App. Состояние уже есть, поэтому color установлено на "blue". Он не инициализируется с помощью "red". DOM обновляется с результатом.

Через секунду тайм-аут разрешается, и setColor("purple"); устанавливает цвет в состоянии на "purple", что заставляет App запускаться снова. Состояние уже есть, поэтому color установлено на "purple".

Каждый раз, когда DOM обновляется, в revealColor передается новая функция onClick, которая закрывается над переменной color из самого последнего вызова App.


Между тем, функция, которую вы передаете useEffect, запускается только один раз (потому что вы передали [] в качестве второго аргумента), поэтому закрытая переменная color является исходной, и вы регистрируете "red" там.

Другие вопросы по теме