Учимся понимать машину и асинхронно взрываем себе мозг :)
Итак, в бар входит в ковбой и требует выпивку - это объявление, декларация намерений.
Бармен спрашивает - чем будешь платить: деньгами, отдашь пистолет или отработаешь мытьем посуды? - Я заплачу, - отвечает ковбой, - у меня есть деньги. - Это определение типа данных.
Тогда плати 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?