← Назад к вопросам
Как использовать отношения между моделями?
2.0 Middle🔥 121 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование отношений между моделями на фронтенде
Отношения между моделями часто встречаются при работе с данными. На фронтенде нужно правильно работать с этими отношениями при запросах к API и управлении состоянием.
Концепция отношений
Отношения между моделями:
- One-to-Many — один элемент может иметь множество подчинённых (автор имеет много статей)
- Many-to-One — множество элементов относятся к одному (много статей относятся к одному автору)
- Many-to-Many — элементы взаимно связаны (студенты и курсы)
Способ 1: Получение данных с вложенными отношениями
Когда API возвращает вложенные данные:
fetch('/api/users/1')
.then(res => res.json())
.then(data => {
console.log(data)
})
Способ 2: Раздельные запросы для отношений
Иногда API требует отдельные запросы для получения связанных данных:
import { useState, useEffect } from 'react'
export function UserProfile({ userId }) {
const [user, setUser] = useState(null)
const [posts, setPosts] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
Promise.all([
fetch(`/api/users/${userId}`).then(r => r.json()),
fetch(`/api/users/${userId}/posts`).then(r => r.json())
])
.then(([userData, postsData]) => {
setUser(userData)
setPosts(postsData)
setLoading(false)
})
}, [userId])
if (loading) return <p>Loading...</p>
return (
<div>
<h1>{user.name}</h1>
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
)
}
Способ 3: Нормализация данных
При работе с большим количеством отношений полезно нормализовать данные:
const normalized = {
users: {
1: { id: 1, name: 'John', postIds: [1, 2] }
},
posts: {
1: { id: 1, title: 'Post 1', authorId: 1 },
2: { id: 2, title: 'Post 2', authorId: 1 }
}
}
const getUserWithPosts = (userId) => {
const user = normalized.users[userId]
const posts = user.postIds.map(postId => normalized.posts[postId])
return { ...user, posts }
}
Способ 4: Many-to-Many отношения
При many-to-many отношениях элементы взаимно связаны:
const courseData = {
id: 1,
title: 'React Basics',
studentIds: [1, 2, 3]
}
export function CourseEnrollment({ courseId, studentId }) {
const [enrolled, setEnrolled] = useState(false)
const enrollStudent = async () => {
const response = await fetch(`/api/courses/${courseId}/enroll`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ studentId })
})
if (response.ok) {
setEnrolled(true)
}
}
return (
<button onClick={enrollStudent} disabled={enrolled}>
{enrolled ? 'Enrolled' : 'Enroll'}
</button>
)
}
Способ 5: Использование библиотек
Сложные отношения проще управлять с библиотеками для нормализации:
import { normalize, schema } from 'normalizr'
const user = new schema.Entity('users')
const post = new schema.Entity('posts', {
author: user
})
const mySchema = [post]
const data = [
{
id: 1,
title: 'Post 1',
author: { id: 1, name: 'John' }
}
]
const normalized = normalize(data, mySchema)
Способ 6: React Query для управления отношениями
Современные библиотеки упрощают работу с отношениями:
import { useQuery } from '@tanstack/react-query'
export function UserProfile({ userId }) {
const { data: user, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetch(`/api/users/${userId}`).then(r => r.json())
})
const { data: posts } = useQuery({
queryKey: ['posts', userId],
queryFn: () => fetch(`/api/users/${userId}/posts`).then(r => r.json()),
enabled: !!user
})
if (isLoading) return <p>Loading...</p>
return (
<div>
<h1>{user.name}</h1>
<ul>
{posts?.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</div>
)
}
Ключевые моменты
- Вложенные данные — API может возвращать отношения в одном запросе
- Раздельные запросы — используй Promise.all для параллельных запросов
- Нормализация — избегай дублирования данных в состоянии
- Many-to-Many — управляй связями через ID массивы
- Библиотеки — normalizr, React Query упрощают работу с отношениями
Правильная работа с отношениями между моделями критична для эффективного управления сложными данными.