Skip to content

sprint-4/step-1#7

Open
DovgiyA wants to merge 2 commits into
masterfrom
sprint-4/step-1-
Open

sprint-4/step-1#7
DovgiyA wants to merge 2 commits into
masterfrom
sprint-4/step-1-

Conversation

@DovgiyA

@DovgiyA DovgiyA commented Nov 16, 2023

Copy link
Copy Markdown
Owner

No description provided.

@gennady-bars gennady-bars left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здравствуйте. (Нужно развернуть общий комментарий ↓)

Посмотрите на гитхабе все комментарии к коду (нужно прокрутить вниз страницу там)

Работа проделана огромная:

  • Отлично, что знаете про тип Response для ответа от сервера
  • Отлично, что знаете про тип KeyboardEvent для событий клавиатуры
  • Хорошая типизация компонентов

но есть некоторые недочеты:

  • Скрин https://disk.yandex.ru/i/TbTIhetRnYCJzQ приложение ломается при перезагрузке страницы с открытым попапом ингредиента и при вставке ссылки в браузер
  • Все события обработчиков нужно правильно типизировать. Это легко сделать. Для onChange есть тип ChangeEvent<HTMLInputElement>, а для onSubmit есть FormEvent<HTMLFormElement> в библиотеке react. Для обычных функций есть тип SyntheticEvent для их событий. Тип Response для ответа от сервера, тип KeyboardEvent для событий клавиатуры, тип RouteProps для рутов
  • <AppHeader /> нужно поместить только в App, чтобы любая страница была с этим хэдером. Не нужно дублировать его в каждой странице

Можно лучше

  • import { useDispatch, useSelector } from 'react-redux'; такого больше не должно быть в проекте. Хуки useDispatch, useSelector нужно типизировать 1 раз в отдельном файле и заменить их во всем проекте на свои, а не из библиотеки react-redux . Вот ссылка на документацию по их типизации https://redux.js.org/usage/usage-with-typescript#define-typed-hooks
  • (store: any) или (state: RootState) уже не нужно будет типизировать вручную стейт, когда замените везде хук useSelector. Нужно будет удалить дублирование типизации
  • Есть небольшая хитрость: можно всегда проверить, какой тип у функции или события. Для этого нужно навести мышкой на атрибут onChange, onSubmit, onClick и тд. Там высветится типизация того, что принимают эти атрибуты.

Comment thread src/utils/request.ts Outdated
import { REFRESH } from "../constants/constants";

const checkResponse = (res) => {
const checkResponse = (res: Response): Promise<any> => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

: Promise<any> не нужно указывать тут. Все автоматом определяется

Comment thread src/utils/request.ts Outdated
import { REFRESH } from "../constants/constants";

const checkResponse = (res) => {
const checkResponse = (res: Response): Promise<any> => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отлично, что знаете про тип Response для ответа от сервера


const sendForm = e => {
e.preventDefault();
const sendForm = (event: React.SyntheticEvent): void => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все события обработчиков нужно правильно типизировать. Это легко сделать. Для onChange есть тип ChangeEvent<HTMLInputElement>, а для onSubmit есть FormEvent<HTMLFormElement> в библиотеке react. Для обычных функций есть тип SyntheticEvent для их событий. Тип Response для ответа от сервера, тип KeyboardEvent для событий клавиатуры, тип RouteProps для рутов


return (<>
<div className={styles.wrapper}>
<AppHeader className={styles.header} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<AppHeader /> нужно поместить только в App, чтобы любая страница была с этим хэдером. Не нужно дублировать его в каждой странице

@@ -4,14 +4,13 @@ import { useDrag, useDrop } from "react-dnd";
import { useDispatch, useSelector } from 'react-redux';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно лучше

import { useDispatch, useSelector } from 'react-redux'; такого больше не должно быть в проекте. Хуки useDispatch, useSelector нужно типизировать 1 раз в отдельном файле и заменить их во всем проекте на свои, а не из библиотеки react-redux . Вот ссылка на документацию по их типизации https://redux.js.org/usage/usage-with-typescript#define-typed-hooks


useEffect(() => {
const onKey = (event) => {
const onKey = (event: KeyboardEvent) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отлично, что знаете про тип KeyboardEvent для событий клавиатуры

export const BurgerConstructor = ({className}) => {
export const BurgerConstructor = ({className}: ClassNameI) => {

const [isOpen, setIsOpen] = useState(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно лучше

Если интересно, можно создать кастомный хук для управления модальным окном:

import { useState, useCallback } from "react";

// кастомные хуки всегда должны начинаться с глагола `use`, чтобы реакт понял, что это хук. Он следит за их вызовами
export const useModal = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  // `useCallback` нужен для того, чтобы зафиксировать ссылку на функцию. Таким образом уменьшится кол-во перерисовок компонента, куда будет передана эта функция
  const openModal = useCallback(() => {
    setIsModalOpen(true);
  }, []);

  const closeModal = useCallback(() => {
    setIsModalOpen(false);
  }, []);

  return {
    isModalOpen,
    openModal,
    closeModal,
  };
};

Этот код помещают в отдельный файл useModal.js в папке hooks и импортируют функцию туда, где нужно создать показатели открытости/закрытости попапа (у каждого попапа они свои)

И теперь нужно просто вызывать хук в том компоненте, где нужно управлять попапом. Всего одна строчка кода будет (под каждый попап своя):

  const { isModalOpen, openModal, closeModal } = useModal();

@gennady-bars gennady-bars left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поздравляю! Ваша работа принята.

Вы отлично потрудились.

Удачного дальнейшего обучения.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants