Разница между умным и презентационным компонентами?

В архитектуре Angular есть понятие разделения компонентов на умные (smart) и презентационные (presentational) компоненты. Это практика, которая помогает структурировать код и улучшить его читаемость, поддерживаемость и переиспользуемость. Разберем разницу между этими двумя типами компонентов подробнее:

  1. Умные компоненты (Smart Components):
    • Отвечают за управление состоянием и бизнес-логикой.
    • Обычно связаны с сервисами и хранилищем состояния (например, ngrx/store).
    • Используются для получения и обработки данных, взаимодействия с внешними сервисами или API.
    • Определяют логику, обработку событий и передачу данных в презентационные компоненты.
    • Обычно имеют более общие и абстрактные имена, связанные с функциональностью, например, UserListComponent.

Вот пример умного компонента в Angular:

import { Component, OnInit } from '@angular/core'
import { UserService } from './user.service'

@Component({
	selector: 'app-user-list',
	template: `
		<h2>User List</h2>
		<ul>
			<li *ngFor="let user of users">{{ user.name }}</li>
		</ul>
	`
})
export class UserListComponent implements OnInit {
	users: User[]

	constructor(private userService: UserService) {}

	ngOnInit() {
		this.userService.getUsers().subscribe((users) => {
			this.users = users
		})
	}
}
  1. Презентационные компоненты (Presentational Components):
    • Отвечают за отображение данных и пользовательский интерфейс.
    • Не зависят от конкретной бизнес-логики и состояния приложения.
    • Принимают данные через входные свойства (inputs) и генерируют события через выходные свойства (outputs).
    • Отвечают за отображение данных в удобной и понятной форме, например, форматирование дат, фильтрация или сортировка.
    • Могут быть переиспользованы в разных частях приложения.
    • Обычно имеют более специфичные имена, связанные с отображаемыми данными или элементами интерфейса, например, UserCardComponent.

Вот пример презентационного компонента в Angular:

import { Component, Input, Output, EventEmitter } from '@angular/core'
import { User } from './user.model'

@Component({
	selector: 'app-user-card',
	template: `
    <div class="user-card">
      <h3>{{ user.name }}</h3

      <p>Email: {{ user.email }}</p>
      <button (click)="editUser()">Edit</button>
    </div>
  `,
	styles: [
		`
			.user-card {
				border: 1px solid #ccc;
				padding: 10px;
				margin-bottom: 10px;
			}
		`
	]
})
export class UserCardComponent {
	@Input() user: User
	@Output() edit = new EventEmitter<void>()

	editUser() {
		this.edit.emit()
	}
}

В данном примере UserCardComponent принимает объект пользователя (user) через входное свойство @Input(), отображает его данные и генерирует событие edit при нажатии на кнопку "Edit".

Использование умных и презентационных компонентов позволяет лучше структурировать код, повысить его читаемость и облегчить поддержку приложения. Умные компоненты отвечают за управление состоянием и бизнес-логикой, тогда как презентационные компоненты сосредоточены на отображении данных и пользовательском интерфейсе. Это помогает разделить ответственности между компонентами и создать более гибкую и переиспользуемую архитектуру приложения.