Нормализация данных — один из ключевых подходов при работе с состоянием приложений на фреймворках типа Inferno. Она позволяет избежать дублирования информации, упростить обновление состояния и повысить производительность компонентов.
Нормализация данных заключается в представлении сложных вложенных структур в виде плоских объектов с уникальными идентификаторами. Вместо хранения повторяющихся объектов внутри разных частей состояния используется один источник истины, а ссылки на него хранятся через идентификаторы.
Пример до нормализации:
const state = {
posts: [
{
id: 1,
title: "Первый пост",
author: {
id: 1,
name: "Иван"
}
},
{
id: 2,
title: "Второй пост",
author: {
id: 1,
name: "Иван"
}
}
]
};
Здесь информация об авторе повторяется в каждом посте. Любое изменение имени автора потребует обхода всех постов.
После нормализации структура состояния может выглядеть так:
const state = {
posts: {
1: { id: 1, title: "Первый пост", authorId: 1 },
2: { id: 2, title: "Второй пост", authorId: 1 }
},
authors: {
1: { id: 1, name: "Иван" }
}
};
Теперь данные об авторе хранятся отдельно и изменяются в одном месте.
Inferno использует Virtual DOM и оптимизированные рендеринг-алгоритмы. При нормализованной структуре состояние можно обновлять точечно, не вызывая лишние перерендеринги. Основные подходы:
Использование идентификаторов: ссылки на
сущности передаются через id. Компоненты получают данные из
плоских мап, что облегчает сравнение старого и нового
состояния.
Immutable-подход: при обновлении состояния создаются новые объекты для изменяемых сущностей, а неизменные остаются прежними. Это обеспечивает корректное определение изменений через сравнение ссылок.
Селекторы: функции, которые извлекают из плоской структуры необходимые данные для компонента. Например:
function getPostWithAuthor(state, postId) {
const post = state.posts[postId];
const author = state.authors[post.authorId];
return { ...post, author };
}
Селекторы скрывают внутреннюю структуру состояния, упрощая работу компонентов.
При нормализации важно корректно моделировать связи между объектами:
id.Пример отношения «один ко многим»:
const state = {
posts: {
1: { id: 1, title: "Первый пост", commentIds: [1, 2] }
},
comments: {
1: { id: 1, text: "Отлично!" },
2: { id: 2, text: "Супер!" }
}
};
В Inferno состояние может храниться как глобально, так и локально. Для локального состояния нормализация помогает:
Пример локального состояния с нормализацией:
function PostsList() {
const [state, setState] = Inferno.useState({
posts: {
1: { id: 1, title: "Первый пост", authorId: 1 }
},
authors: {
1: { id: 1, name: "Иван" }
}
});
const addPost = (post) => {
setState(prev => ({
...prev,
posts: { ...prev.posts, [post.id]: post }
}));
};
const getPostWithAuthor = (postId) => {
const post = state.posts[postId];
const author = state.authors[post.authorId];
return { ...post, author };
};
return state.posts ? (
<ul>
{Object.values(state.posts).map(post => (
<li key={post.id}>
{getPostWithAuthor(post.id).title} — {getPostWithAuthor(post.id).author.name}
</li>
))}
</ul>
) : null;
}
Нормализация данных является фундаментальной практикой при построении масштабируемых приложений на Inferno. Она обеспечивает чистоту состояния, оптимизацию рендеринга и удобство управления связями между сущностями.