Учимся понимать машину и асинхронно взрываем себе мозг :) Итак, в бар входит в ковбой и требует выпивку - это объявление, декларация намерений. Бармен спрашивает - чем будешь платить: деньгами, отдашь пистолет или отработаешь мытьем посуды? - Я заплачу, - отвечает ковбой, - у меня есть деньги. - Это определение типа данных. Тогда плати 5 баксов и получай выпивку - Ковбой платит и веселье начинается - Это инициализация, присвоение начального значения, запуск процесса в работу. Шаг 1. Инициализируем переменую state со значением undefined. Машина сохраняет ее в памяти со значением undefined. Шаг 2. Инициализируем функцию useState в аргуаментах ждем парметр defaultValue с условием, если state === undefined присвой state пустой обьект в который положи ключ field со значением defaultValue. Машина видит, что мы инициализировали функцию useState со значением state = undefined. Шаг 3. Инициализируем функцию setState в аргуаментах ждем парметр value в теле функции вызываем функцию setTimeout, которой в объект state записываем значение ключ field со значением value. Данная функция отправляется в стек, но так как внутри функции setState, находится функция setTimeout, которая не является частью JavaScript движка, а является Web API браузера как дополнительный функционал она отправляется в Web API. Далее Web API браузера запускает таймер в 2000ms, оставляя на фоне setTimeout(). Шаг 4. Следующая строка в нашем скрипте это console.log("state", state); , отправленное в стек и выкинутое оттуда после выполнения. Это получается наш первый выкинутый в консоль результат в данный момент наш state = undefined, поэтому получаем: 1. "state" undefined Шаг 5. Инициализируем переменую count и делаем вызов функции useState(со значением 5) и присваеваем результат перемной count. В аргументе defaultValue функция useState теперь хранится значение 5. Теперь в функции у нас идет проверка условий if(state === undefined), так как state у нас по прежнему undefined условие true, поэтому оно выполняется дальше создаем пустой объект state = {};, переходим к следуещему условию создаем в объекте ключ field со значением defaultValue получается field: 5, так как мы вызвали функцию useState и положили в defaultValue = 5. Теперь return нам возвращает Return value 5. Здесь тоже мне не свосем понятно, когда функция useState попадает в стек при вызове, как сейчас или при инициализации она сразу попадает в стек и жет своего выполнения? Шаг 6. Следующая строка в нашем скрипте это console.log("count 1", count); , отправляется в стек и выкидывается оттуда после выполнения. В результате мы получаем наш второй вывод в консоль. 2. "count 1" 5 На этом месте все, я уже ничего не понимаю на самом деле, что происходит. Во-первых где наша функция setState со своим setTimeout она здесь вообще в процесе участвует или мы про нее вообще забыли? Откуда при инициализации функции setState появился count со значением undefined (откуда он вообще count этот берется)? В этом шаге мы получаем в консоль лог count из инициализированной переменой var count = useState(5); или он к нам все-таки прилетает из функции setState?