Добавить список городов в главное меню
Выполняется
Проект: Пивная карта
Планируемый запуск: | Дата начала: | 25.04.2021 | Планируемое завершение: | Дата завершения: |
Проект | Задача | Статус | Дата постановки | Начало | Конец | Кто создал |
---|---|---|---|---|---|---|
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 05.05.2021 04:04:37 | 05.05.2021 04:31:49 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 05.05.2021 02:57:02 | 05.05.2021 03:53:30 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 04.05.2021 14:03:24 | 04.05.2021 14:19:13 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 04.05.2021 11:53:52 | 04.05.2021 12:15:34 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 04.05.2021 11:42:53 | 04.05.2021 12:58:28 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 04.05.2021 11:15:16 | 04.05.2021 11:37:01 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 04.05.2021 10:04:52 | 04.05.2021 10:52:57 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 30.04.2021 08:52:23 | 30.04.2021 10:58:49 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 30.04.2021 06:26:13 | 30.04.2021 06:35:01 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 30.04.2021 06:25:51 | 30.04.2021 06:26:12 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 30.04.2021 05:47:37 | 30.04.2021 06:03:37 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 27.04.2021 16:52:19 | 27.04.2021 17:11:50 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 25.04.2021 15:25:51 | 25.04.2021 15:34:00 | |
Пивная карта | Добавить список городов в главное меню | Выполняется | 04.04.2021 07:14:03 | 25.04.2021 04:50:31 | 25.04.2021 05:00:48 |
Николай, приветствую!
Подступился к этой задачке.
Правильно понимаю, что не хватает двух вещей: подключения запроса gql и завмого вывода в меню?
Дима, привет!
Нет, неправильно. Там в меню уже есть список городов, просто он не выведен. Надо в этом месте удалить переменную citiesList и вставить ее в нужном месте в меню, при этом скорее всего стили надо будет поправить.
Я его грешным делом пробовал как <citiesList/> вывести перед Контакты, но ничего не вывелось)
Но то, что паттерн был верный - уже радует))))
его надо как {citiesList}
Супер, спаибо!
Николай, привет! Настраиваю отображение выпадающего меню с городами и запутался) Верстка имеет признаки bootstrap, а ты вроде как используешь material-ui. Вопрос: я что-то не понял или лучше перевести всё меню на material-ui?
Дима, привет!
Тебе ни то, ни другое не нужно. Запомни: все стили делаем на styled-components. Там уже вроде как все есть. Вот смотри стили для выпадашек. Вот метод на открытие/закрытие меню. Вот навешивается ивент на документ, чтобы по клику где угодно меню закрылось. Это все для мобильной версии, для меню, но бери это за основу и себе доделай.
Если что не понятно будет, спрашивай.
Понял, спасибо!
Не за что!
Николай, туплю: понимание, как сделать, так и не пришло. Нужна твоя помощь)
Дима, полдела - это правильно сформулировать задачу. Сформулируй четко что именно у тебя не получается. Нельзя вот так просто сказать "У меня не получается, сделай за меня". Я так не понимаю что тебе ясно, а что не ясно. Надо четко обозначать каждый неясный момент. Цикла написать, фильтрацию, поиск, стили прописать, навесить ивенты и т.д. и т.п - это куча отдельных задачек. И так будет всегда.
Можешь в отдельные подзадачки (чтобы проще потом искать), можешь просто комментами писать отдельно по каждой. Как хочешь.
Понял, учусь формулировать.
Но тут как раз комплексная проблема:
я понимаю, как сформирован список городов, но как и на какой конкретно элемент повесить событие, почему выпадающий блок, если поствить в меню, отображается обычным списком и как toggleMenu связано со стилями [opened] в styled-component?
Постараюсь выделить более точную задачу и напишу.
Николай, вопрос:
Это всё механика открытия и закрытия бургера на мобверсии и надо на базе этого кода сделать выпадающее меню по городам?
>> и надо на базе этого кода сделать выпадающее меню по городам?
Да. То есть тебе надо разобраться что тот код делает и адаптировать его под себя, то есть написать похожий код, который будет открывать и закрывать пункты меню.
>> Запутался:
Это потому что ты еще не освоил замыкания и области видимости переменных :) Ну и потому что я такой плохой - не думаю над уникальностью имен переменных.
Вот это первая переменная, которая есть суть выполнения функции useMemo() и которую и надо вывести ниже в меню.
А вот это вторая переменная, которая объявлена в теле функции, набиваемая в цикле и возвращаемая ниже в виде пункта меню с подменю.
Понял, спасибо!
Николай, приветствую!
Добавляю такой код:
И повесил на:
Заменив ссылку на кнопку.
В стиле списка городов - display: citiesOpened ? 'block' : 'none',
Но возникает ошибка:
Unhandled Runtime Error
TypeError: Cannot read property 'length' of undefined
Source
src/pages/_App/Layout/MainMenu/index.tsx (149:33) @ MainMenu
147 | const [opened, openedSetter] = useState(false) 148 | > 149 | const toggleMenu = useCallback(() => { | ^ 150 | openedSetter(!opened) 151 | }, [opened]) 152 |Где я не прав?
Дима, привет!
Во-первых, прежде чем задавать такие вопросы, выливай коммит, хотя бы в какую-нибудь отдельную ветку (и в комментарии пиши, если это не основная ветка, куда вылил).
git push --no-verify
Согласись, мне проще будет?
Сделл коммит: https://github.com/Pivkarta/pivkarta.ru-2/commit/cb1db19d983184dbe5f58c5b04a8993f0d0078ea
А у тебя в VSCode разве нет этих ошибок?
Нету. Что-то из дополнений не стоит?
Eslint надо ставить.
И надо потом убедиться, что он активен:
Если перечеркнут, надо по нему кликнуть и во всплывашке разрешить его (Allow).
Если заработает, то он тебе покажет вот такое:
Собственно, эту ошибку и в браузере видно, и на ошибки в браузере обязательно надо обращать внимание.
Это распространенная ошибка, которой не должно быть: все хуки должны выполняться обязательно и до их выполнения никак логика не должна обрываться по каким-либо условиям.
У тебя же ошибка в том, что useState() прописан внутри useMemo(). То есть хуки внутри хуков тоже нельзя прописывать.
В общем, поправь хуки и должно заработать (у меня заработало, но не буду выливать, тебе надо самому попытаться).
Оказалось ,не включил Eslint...
Про хуки понял - исправляюсь
Давай. Исправляй и выливай коммит.
Вроде сделаал: https://github.com/Pivkarta/pivkarta.ru-2/commit/e577598920a90afe36aff5b9a6b024b77b9407ef
Посмотришь?
Технически работает. Но результат надо улучшить.
1. Избавиться от style={...}, перенести стили в styles.ts
2. Навесить на document обработчик, чтобы по клику меню закрывалось. А то сейчас только по клику в сам корневой пункт меню.
Понял, правлю)
Есть: https://github.com/Pivkarta/pivkarta.ru-2/commit/f658013e24f93ae1605b6eeb16296785036ea2c6
Единственное, чего не понял, это как в стили запихать это: display: citiesOpened ? 'block' : 'none',
Пока я делаю, вопрос: ты вот здесь точно все понимаешь? Каждую конструкцию? https://github.com/Pivkarta/pivkarta.ru-2/blob/f658013e24f93ae1605b6eeb16296785036ea2c6/src/pages/_App/Layout/MainMenu/index.tsx#L46-L60
Попробую описать:
Если citiesOpened==false, то ничего не делаем.
Иначе - создаём функцию closeCitiesOpenedEvent , которая сеттеру citiesOpenedSetter назначает false.
Слушатель window.document.addEventListener('click', closeCitiesOpenedEvent) ждет клика на докуументе, чтобы запустить closeCitiesOpenedEvent.
window.document.removeEventListener('click', closeCitiesOpenedEvent) - обнуляем слушателя.
А вот это что законструкция?
return () => { ... }
В целом ты все верно описал, но вот это:
>> А вот это что законструкция?
return () => { ... }
Как раз и выдает твою ошибку: ты объявление функции воспринимаешь буквально как уже выполнение функции, а это совсем не так. Функция выполняется только когда ее вызывают. До вызова все то, что описано в теле этой функции, не выполняется и никакого значения не имеет.
Если точнее, то скорее всего ты это понимаешь, но все же надо правильно говорить и в предложении, где есть объявление функций и вызов их, так и говорить "объявляем", "вызывает" (или "вызывает", если явно хочешь указать на того, кто вызывает (окно, документ, ссылка)).
return () => {...} в хуке useEffect - это возвращаемая не обязательная функция, которая выполняется каждый раз при ререндеринге этого компонента (при изменении стейста и пропсов). Только важно учитывать второй параметр - deps. В твоем случае это [citiesOpened]. То есть этот хук будет перевыполняться только если меняется переменная citiesOpened (Речь о повторном вызове. В первый раз обязательно хук выполнится).
Так вот, эта возвращаемая функция выполняется перед повторным выполнением и размонтированием компонента (то есть при удалении из DOM). Тут несколько сложно, но со временем поймешь. Коротко можно только сказать так: при срабатывании хука навешивается ивент на документ, а когда хук удаляется, то выполняется этот возвращаемый метод (если он прописан в хуке). В нашем случае он нужен для того, чтобы снять наш слушатель с документа. А иначе сколько раз раз выполнится хук, столько и событий навесится на документ, и они скорее всего все будут не актуальны. Это вызовет утечку памяти.
В общем, твоя задача в рамках этих небольших заданий научиться понимать все в рамках этих заданий. Если что-то не понятно, обязательно спрашивай. Дьявол кроется в мелочах.
Амен)
Спасибо!
Как думаешь, чего следующее ковырять?
>> Единственное, чего не понял, это как в стили запихать это: display: citiesOpened ? 'block' : 'none',
>> Как думаешь, чего следующее ковырять?
Сейчас я поправлю нейминг в стилях и попробуй тогда вынести в отдельный компонент DropdownMenu, чтобы в нем уже были как положено interfaces.ts и styles.ts, и чтобы его можно было импортировать в меню. Очень хорошая задачка.