Можешь объяснить, как работает в данном случае тернарное выражение: Не понимаю почему перед .done стоит точка.

Работа со стейтем в функциональных и классовых компонентах немного отличается, в том плане, что в классовых ты работаешь с полным объектом, типа такого: и можешь обращаться напрямую к его свойствам типа this.state.done В функциональных же ты не напрямую со стейтом работаешь, а с его свойствами типа так: Во втором случае у тебя стейт как бы всегда отсутствует, есть только его значения (которые могут быть пустыми). В первом же случае (в классовых) у тебя стейт может не быть, а может и быть. То есть если ты раз задал this.setState({done: true}), то у тебя this.state уже есть всегда в течение жизни компонента. Таким образом у тебя логическая ошибка в этом условии: У тебя всегда есть this.state и получается, что всегда задается done: true. То есть надо было проверять то есть проверять отсутствие стейта, а не его наличие. Ну, это в твоем случае. А вообще в таких случаях делают так: То есть устанавливают инвертированное значение.

Дима, вот у тебя есть кусок кода: В нем есть стайлед-компоненты DropdownMenuBoxStyled и DropdownMenuStyled, которые берутся из ./styled.ts Надо их вынести в отдельный компонент DropdownMenu (там, скорее всего, придется переименовать компоненты DropdownMenuBoxStyled и DropdownMenuStyled, чтобы было логичней, так как сейчас получается, что компонент с более коротким названием является вложенным в компонент с более длинным названием, что противоречит интуитивнопонятному неймингу). То есть тебе надо создать компонент DropdownMenu, чтобы ты в главном меню мог вызывать так: linkProps - это я общий набор параметров для ссылки обозначил. Фактически же да, ты будешь перечислять явно типа такого: А в том компоненте будет типа так: Но здесь, как видишь, other попадает в корневой тег меню, а не в ссылку, и в данной реализации получается, что у тебя ссылка имеет на вход очень ограниченное число параметров, хотя может быть сильно больше, чем ты изначально предполагаешь. Возможно имеет смысл href, title, name вынести в отдельный параметр типа linkProps, чтобы можно было сделать так: Тогда у тебя получится более гибкий компонент, особенное если ты найдешь способ параметру linkProps задать одной конструкцией все возможные свойства ссылок:-) (Это тебе дополнительное субзадание, которое попытайся решить, но если не получится, то не фанатей).

Николай, приветствую! Для оценки правильности поставленной задачи, посмитри, пожалуйста, тезисы. А то может я вообще не правильно понимаю, что делаю)))) Компонент должен принимать: - название верхнего пункта меню - список подпунктов выпадающего меню - отображать все это добро в верхнем меню.

Единственное, чего не понял, это как в стили запихать это: display: citiesOpened ? 'block' : 'none', Написал ответ здесь. >> Как думаешь, чего следующее ковырять? Сейчас я поправлю нейминг в стилях и попробуй тогда вынести в отдельный компонент DropdownMenu, чтобы в нем уже были как положено interfaces.ts и styles.ts, и чтобы его можно было импортировать в меню. Очень хорошая задачка.

Амен) Спасибо! Как думаешь, чего следующее ковырять?

В целом ты все верно описал, но вот это: >> А вот это что законструкция? return () => { ... } Как раз и выдает твою ошибку: ты объявление функции воспринимаешь буквально как уже выполнение функции, а это совсем не так. Функция выполняется только когда ее вызывают. До вызова все то, что описано в теле этой функции, не выполняется и никакого значения не имеет. Если точнее, то скорее всего ты это понимаешь, но все же надо правильно говорить и в предложении, где есть объявление функций и вызов их, так и говорить "объявляем", "вызывает" (или "вызывает", если явно хочешь указать на того, кто вызывает (окно, документ, ссылка)). return () => {...} в хуке useEffect - это возвращаемая не обязательная функция, которая выполняется каждый раз при ререндеринге этого компонента (при изменении стейста и пропсов). Только важно учитывать второй параметр - deps. В твоем случае это [citiesOpened]. То есть этот хук будет перевыполняться только если меняется переменная citiesOpened (Речь о повторном вызове. В первый раз обязательно хук выполнится). Так вот, эта возвращаемая функция выполняется перед повторным выполнением и размонтированием компонента (то есть при удалении из DOM). Тут несколько сложно, но со временем поймешь. Коротко можно только сказать так: при срабатывании хука навешивается ивент на документ, а когда хук удаляется, то выполняется этот возвращаемый метод (если он прописан в хуке). В нашем случае он нужен для того, чтобы снять наш слушатель с документа. А иначе сколько раз раз выполнится хук, столько и событий навесится на документ, и они скорее всего все будут не актуальны. Это вызовет утечку памяти. В общем, твоя задача в рамках этих небольших заданий научиться понимать все в рамках этих заданий. Если что-то не понятно, обязательно спрашивай. Дьявол кроется в мелочах.

Попробую описать: Если citiesOpened==false, то ничего не делаем. Иначе - создаём функцию closeCitiesOpenedEvent , которая сеттеру citiesOpenedSetter назначает false. Слушатель window.document.addEventListener('click', closeCitiesOpenedEvent) ждет клика на докуументе, чтобы запустить closeCitiesOpenedEvent. window.document.removeEventListener('click', closeCitiesOpenedEvent) - обнуляем слушателя. А вот это что законструкция? return () => { ... }