Сравнение на равенство двух объектов (в том числе массивов) всегда возвращает false, так как происходит сравнение ссылок.
Плюсы использования const/let в отличии от var.
- Область видимости — блок. У var область видимости функция либо глобальная.
Пример:
function test() {
let a = 123
for (let i = 0; i < 1; i++) {
let a = 0
console.log(a)
}
console.log(a)
}
test()
Выведет в консоль 0, потом 123, так как создались две разые переменные, каждая в отдельной области видимости.
- Если вызвать переменную, объявленную через const/let до ее создания, то возникнет ошибка (которая будет видна в консоли), что позволит найти ошибку в коде на более раннем этапе разработки.
- При использовании в цикле, для каждой итерации создаётся своя переменная.
Пример:
function makeArmy() {
let shooters = []
for (let i = 0; i < 10; i++) {
shooters.push(function () {
console.log(i)
})
}
return shooters
}
const army = makeArmy()
army.forEach((item) => {
item()
})
В консоль выведутся числа от 0 до 9, так как для каждой итерации создаётся своя переменная и, как следствие, на каждой итерации произойдет замыкание для переменной i в функцию, которая добавляется в массив.
const в отличии от let не позволяет изменять переменную, что позволяет допустить меньше ошибок в коде.
Промисы создают микрозадачи, а setTimeout макрозадачи. Микрозадачи выполняются раньше макрозадач. Следовательно, то, что было в обработчике промиса, выполнится раньше, чем то, что было в setTimeout.
Только на сервере. Либо в инструментах разработчика.
- CSS
- Inline-стили
- styled-components
- CSS-модули
- Обернуть в memo
- При необходимости обернуть в useCallback и в useMemo передаваемые пропсы
- Создавать стейт и вызывать контекст как можно ниже в дереве компонентов (только там, где они нужны), чтобы лишние рендеры не происходили в компонентах, в которых этот стейт или контекст не используется.
- При обновлении значений в контексте происходит рендер всех компонентов, лежащих ниже провайдера контекста в иерархии компонентов.
- Можно нечаянно обратиться не к тому провайдеру (в случае, если компонент обернут в провайдер одного и того же контекста несколько раз)
- Create React App устарел.
- Пришлось установить npm-пакет uuid.
- Не следует грузить иконки отдельными запросами.
- Не следует создавать модалку в каждом элементе списка.
- Лучше использовать clsx или подобную библиотеку для динамических CSS-классов в угоду читаемости кода.
- Нужно выносить модалку за корневой элемент при помощи портала.
- https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Modal/ModalCreateItem.tsx#L66
Нечитаемый код. Стоит вынести в функцию. Кроме того, здесь баг.
name
? () => {
dispatch(
isCategories
? categoriesAdded({ name, description })
: tasksAdded({
name,
description,
category: setSelected, // баг
})
);
clearState();
setActive(false);
}
: () => {}
Как можно поправить:
const onSubmit = () => {
if (!name) {
return;
}
dispatch(
isCategories
? categoriesAdded({ name, description })
: tasksAdded({
name,
description,
category: selected, // selected вместо setSelected
})
);
clearState();
setActive(false);
}
-
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Lists/ListItem.tsx#L55
Обновлять стейт нужно через сеттер. Если бы на строке 24 был const, а не let, то было бы больше шансов не совершить данную ошибку. -
Не стоит добавлять модалку в DOM-дерево, если она закрыта.
-
Следует убирать скроллбар при открытой модалке.
-
Лучше не задавать фиксированную высоту для list-item, так как в нем может быть много текста.
-
Стоит добавить для класса list-item-col2 правило flex-shrink: 0, чтобы кнопки всегда отображались горизонтально (запретить элементу с классом list-item-col2 сжиматься).
-
Если в открытой модалке зажать левую кнопку мышки в текстовом поле, а затем перенести курсор вне модалки и отпустить мышку, то модалка закроется. Желательно это исправить для лучшего UX. Например, убрать вообще функцию закрытия при нажатии за модалку.
-
Лучше называть редьюсеры в виде add, update, remove внутри слайсов, а экспортировать в виде addCategory, updateCategory, removeCategory и т. д. То есть использовать глаголы настоящего времени и учитывать контекст при именовании.
-
Если перейти на несуществующую страницу, то можно создавать задачу, но список при этом останется пуст. Это вводит в заблуждение. Стоит либо делать редирект на страницу задач, либо не отображать хедер на несуществующей странице.
-
Тесты не должны быть в src.
-
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Lists/ListItem.tsx#L22
Не следует объявлять переменные через запятую. Лучше использовать const, где только можно вместо let. -
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Lists/ListItem.tsx#L31
Стоит создавать менее запутанные наименования классов. -
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/App.css#L6
Нужно описывать CSS правила в отдельных файлах для каждого компонента и подгружать в каждом компоненте свой CSS. -
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Modal/Modal.css#L16
Здесь и еще во многих местах применяется комбинация селекторов. Это не по БЭМ. -
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/Modal/ModalRow.tsx#L18
Это обычный элемент, но зачем-то применяется синтаксис как для модификатора. -
label перекрывает текст в текстовых полях. Данную проблему можно решить при помощи fieldset.
-
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/features/tasksSlice.ts#L57
Лучше не выносить функцию в переменную rm. Аргументы i и arr не нужны. Крайне нежелательно объявлять переменные через запятую (в данном случае rm и rmTaskIndex), так как это сильно сказывается на читаемости. Можно просто уместить в одну строку:const rmTaskIndex = state.findIndex((el) => el.id === action.payload);
-
https://github.com/surfstudio/frontend-interview-test_todo/blob/0f34efeac13406ca6ebdba36ef2ed6d96ea2e504/src/features/tasksSlice.ts#L64
Здесь логичнее использовать forEach -
В модалке не нужно использовать теги header и footer
-
Стоит продумать структуру проекта. Как минимальный вариант создать папку components и туда поместить все компоненты. Также для каждого компонента лучше создавать папку ComponentName, в которой находятся файлы ComponentName.tsx, ComponentName.css и index.ts.