К списку правил
Правила оформления компонентов
Основные правила
- Объявление компонентов через function
- Использование инлайн типов
- Файлы рядом с компонентом
component-name.suffix.tsx - компонент
component-name.suffix.module.css - стили
component-name.suffix.test.ts - тесты
Структура файлов
user-table/
├── user-table.component.tsx
├── user-table.component.module.css
└── user-table.component.test.ts
user-form/
├── user-form.form.tsx
├── user-form.form.module.css
└── user-form.form.test.ts
Объявление компонентов
// ❌ НЕ ПРАВИЛЬНО - стрелочная функция
const UserTable = () => {
return <div>Table</div>;
};
// ❌ НЕ ПРАВИЛЬНО - именованное выражение
const UserTable = function UserTable() {
return <div>Table</div>;
};
// ✅ ПРАВИЛЬНО - объявление функции
export function UserTable() {
return <div>Table</div>;
}
Типизация пропсов
// ❌ НЕ ПРАВИЛЬНО - отдельный интерфейс
interface UserTableProps {
users: User[];
onEdit: (id: number) => void;
}
export function UserTable(props: UserTableProps) {
return <div>Table</div>;
}
// ✅ ПРАВИЛЬНО - инлайн типы
export function UserTable({
users,
onEdit,
}: {
users: User[];
onEdit: (id: number) => void;
}) {
return <div>Table</div>;
}
Структура компонента
'use client'; // Если компонент клиентский
// 1. Импорты
import { useState } from 'react';
import styles from './user-table.component.module.css';
// 2. Компонент
export function UserTable({
users,
onEdit,
}: {
users: User[];
onEdit: (id: number) => void;
}) {
// 2.1 Хуки
const [selectedId, setSelectedId] = useState<number | null>(null);
// 2.2 Обработчики
function handleEdit(id: number) {
setSelectedId(id);
onEdit(id);
}
// 2.3 Рендер
return (
<div className={styles.table}>
{users.map((user) => (
<div key={user.id} className={styles.row}>
<span>{user.name}</span>
<button onClick={() => handleEdit(user.id)}>
Edit
</button>
</div>
))}
</div>
);
}
CSS Modules
/* user-table.component.module.css */
.table {
width: 100%;
}
.row {
display: flex;
align-items: center;
}
Тесты
// user-table.component.test.ts
import { render, screen } from '@testing-library/react';
import { UserTable } from './user-table.component';
describe('UserTable', () => {
it('renders users', () => {
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
];
render(<UserTable users={users} onEdit={() => {}} />);
expect(screen.getByText('John')).toBeInTheDocument();
expect(screen.getByText('Jane')).toBeInTheDocument();
});
});