Это команды, которые будут запускаться из терминала. Их нужно поместить в секцию scripts
"lint": "eslint .",
"lint:fix": "eslint --fix",
"format": "prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",
На windows не отрабатывает команда "format": "prettier --write './**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc"
[error] Invalid configuration file .eslintrc.js
: ENOENT: no such file or directory, open 'D:\Other\G2\React final projects\github-dashboard.prettierrc'
Для фрагментов есть более удобный синтаксис, который не требует импорта из библиотеки React
<Fragment> ... </Fragment => <>...</>
Можно тип репозитория расписать более подробно (только то, что используешь в коде) через arrayOf
.
repositories: PropTypes.array.isRequired,
Аргумент в коллбеке называется repos
, хотя в нём лежит один репозиторий, логичнее назвать repo
repositories.map((repos) => {
Обработчики нужно оборачивать в useCallback
, чтобы функции не создавались заново каждый ререндер
function handleClick() {
dispatch(getRepository(owner, title));
dispatch(getRepositoryStargazers(owner, title));
}
Лучше обернуть в useMemo
, чтобы избежать лишних ненужных вызовов функции formatLastCommitDate
при ререндере.
Если бы это было обычное примитивное значение, то можно не оборачивать.
const formattedLastCommitDate = formatLastCommitDate(lastCommitDate);
Это тоже лучше обернуть в useMemo
const { query, page } = queryString.parse(search);
{/* eslint-disable-next-line react/no-unescaped-entities */}
Так не пойдет. Почитай про само правило https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unescaped-entities.md
Можно заменить
We haven't found anything on your request:
=> {"We haven't found anything on your request:"}
Можно упростить
{!isLoading ? <SearchPagination query={query} currentPage={pageNumber} /> : null}
=> {!isLoading && <SearchPagination query={query} currentPage={pageNumber} />}
Можно вынести из компонента, функция использует только аргументы. Лучше назвать getTotalPagesAmount
. 100 - magic number, можно вынести в константу и дать название.
const countTotalPages = function (totalCount, reposPerPage) {
const pagesAmount = Math.ceil(totalCount / reposPerPage);
if (pagesAmount > 100) {
return 100;
} else {
return pagesAmount;
}
};
Можно добавить параметр query и вынести в функцию вне компонента. Плохое название, потому что точно твоя функция ничего не устанавливает (set), лучше getLinkToPage
function setUrl(page) {
return `/github-dashboard/#/search?query=${query}&page=${page}`;
}
Дальше в разметке много magic numbers, нужно вынести в константы и дать осмысленные названия.
Можно сделать условным не разметку а проп disabled
{currentPage === pagesAmount ? (
<Pagination.Next disabled />
) : (
<Pagination.Next href={setUrl(currentPage + 1)} />
)}
=>
<Pagination.Next disabled={currentPage === pagesAmount} href={setUrl(currentPage + 1)} />
Много похожих кусков можно записать без тернарного оператора
{currentPage === 1 && pagesAmount >= 5 ? (
<Pagination.Item href={setUrl(currentPage + 4)}>{currentPage + 4}</Pagination.Item>
) : null}
=>
{currentPage === 1 && pagesAmount >= 5 && (
<Pagination.Item href={setUrl(currentPage + 4)}>{currentPage + 4}</Pagination.Item>
)}