Riot.js — легковесный и высокопроизводительный фреймворк для создания интерфейсов на JavaScript. Основная сила Riot заключается в его реактивной системе и простоте компонентов. При взаимодействии с внешними источниками данных, такими как REST API и GraphQL, фреймворк предоставляет удобные механизмы для асинхронного обновления состояния компонентов.
Для работы с REST API и GraphQL в Riot.js обычно используют
встроенные возможности fetch или сторонние библиотеки вроде
axios. Riot.js не накладывает ограничений на выбор
инструмента, так как основной акцент сделан на компонентной архитектуре
и реактивности.
Пример базовой настройки fetch:
async function getData(url) {
try {
const response = await fetch(url, { method: 'GET' });
if (!response.ok) throw new Error(`Ошибка: ${response.status}`);
return await response.json();
} catch (error) {
console.error(error);
}
}
При работе с GraphQL запросы чаще всего отправляются методом
POST, а тело запроса содержит объект с полем
query и, при необходимости, variables.
async function fetchGraphQL(query, variables = {}) {
const response = await fetch('https://api.example.com/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables })
});
const result = await response.json();
if (result.errors) console.error(result.errors);
return result.data;
}
Компоненты Riot.js строятся вокруг реактивного состояния, что позволяет легко синхронизировать данные, полученные с сервера, с DOM.
Пример компонента, получающего список пользователей с REST API:
<user-list>
<ul>
<li each={user in users}>{user.name}</li>
</ul>
<script>
import { onMounted, reactive } from 'riot';
const state = reactive({ users: [] });
async function fetchUsers() {
state.users = await getData('https://jsonplaceholder.typicode.com/users');
}
onMounted(() => {
fetchUsers();
});
export default { users: state.users };
</script>
</user-list>
Ключевой момент — использование реактивного объекта
state. Любое изменение массива users
автоматически обновляет DOM благодаря реактивной системе Riot.js.
GraphQL позволяет более гибко управлять данными, запрашивая только необходимые поля. В Riot.js это удобно комбинировать с реактивным состоянием.
Пример запроса пользователей с GraphQL:
<graphql-user-list>
<ul>
<li each={user in users}>{user.name} ({user.email})</li>
</ul>
<script>
import { onMounted, reactive } from 'riot';
const state = reactive({ users: [] });
const query = `
query {
users {
id
name
email
}
}
`;
async function fetchUsers() {
state.users = await fetchGraphQL(query);
}
onMounted(() => {
fetchUsers();
});
export default { users: state.users };
</script>
</graphql-user-list>
Реактивность обеспечивает мгновенное обновление интерфейса при изменении данных. GraphQL сокращает объём передаваемой информации и упрощает управление сложными структурами данных.
Для пользовательского опыта важно отображать статус загрузки и обрабатывать ошибки. Riot.js позволяет это делать через реактивные переменные состояния:
<user-list>
<div if={loading}>Загрузка...</div>
<div if={error}>Ошибка: {error}</div>
<ul if={!loading && !error}>
<li each={user in users}>{user.name}</li>
</ul>
<script>
import { onMounted, reactive } from 'riot';
const state = reactive({ users: [], loading: true, error: null });
async function fetchUsers() {
try {
state.loading = true;
state.users = await getData('https://jsonplaceholder.typicode.com/users');
} catch (e) {
state.error = e.message;
} finally {
state.loading = false;
}
}
onMounted(() => {
fetchUsers();
});
export default { ...state };
</script>
</user-list>
Такой подход обеспечивает чистую реактивную интеграцию API без необходимости дополнительных библиотек для управления состоянием.
REST и GraphQL часто требуют передачи динамических параметров, например идентификаторов ресурсов или фильтров.
REST пример:
async function fetchUserById(id) {
return await getData(`https://jsonplaceholder.typicode.com/users/${id}`);
}
GraphQL пример с переменными:
const query = `
query getUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
async function fetchUser(id) {
return await fetchGraphQL(query, { id });
}
Комбинируя это с реактивным состоянием в Riot.js, можно создавать компоненты с динамическими запросами и мгновенно отображать результаты.
swr/react-query в интеграции с Riot.js.Riot.js позволяет связывать события и асинхронные действия между компонентами:
<parent-component>
<child-component on:userLoaded={handleUserLoaded}></child-component>
<script>
function handleUserLoaded(user) {
console.log('Пользователь загружен:', user);
}
</script>
</parent-component>
Внутри дочернего компонента можно вызывать
this.trigger('userLoaded', user) после получения данных из
REST или GraphQL, обеспечивая реактивное взаимодействие компонентов.
Такой подход обеспечивает чистое разделение логики и представления, упрощает работу с асинхронными данными и позволяет создавать масштабируемые интерфейсы с использованием Riot.js и современных API.