Гид по технологиям

React + Supabase: простое CRUD-приложение

6 min read Web‑разработка Обновлено 02 Jan 2026
React + Supabase: CRUD-приложение
React + Supabase: CRUD-приложение

Ноутбук на столе с открытым редактором кода.

Краткое руководство по созданию простого CRUD-приложения на React с использованием Supabase как BaaS. Показываю, как создать проект Supabase, подключить клиент в React и реализовать операции Create, Read, Update и Delete с практическими примерами кода. В конце — рекомендации по безопасности, тестированию и альтернативные подходы.

Почему Supabase для фронтенд-приложений

Supabase — Backend-as-a-Service (BaaS). Такие провайдеры экономят время разработки. Вместо того чтобы писать и разворачивать отдельный бэкенд, вы получаете готовые сервисы: хранение данных, аутентификацию, realtime и серверные функции. Это удобно для прототипов, внутренних инструментов и многих публичных приложений.

Важно: BaaS не отменяет архитектурного проектирования. Он ускоряет разработку, но накладывает ограничения по гибкости и стоимости на больших масштабах.

Подготовка проекта Supabase

  1. Зарегистрируйтесь на сайте Supabase и войдите в панель управления.
  2. Нажмите кнопку New Project. Кнопка создания нового проекта на странице панели Supabase
  3. Заполните данные проекта и создайте проект. Настройки создания нового проекта на панели Supabase
  4. Выберите раздел SQL Editor в левой панели. Окно SQL-редактора Supabase
  5. Выполните SQL-запрос ниже в SQL-редакторе, чтобы создать демонстрационную таблицу products:
create table products (  
  id bigint generated by default as identity primary key,  
  name text,  
  description text  
);

Примечание: этот пример использует минимальную схему для демонстрации CRUD. В продакшне добавляйте поля аудита (created_at, updated_at), индексы и ограничения целостности.

Создание React-приложения и переменные окружения

Создайте React-приложение (например, через create-react-app). В корне проекта создайте файл .env. На странице Supabase в разделе Settings → API скопируйте значения project URL и public anon key и вставьте их в .env:

REACT_APP_SUPABASE_URL = project URL  
REACT_APP_SUPABASE_ANON_KEY = public anon key

Установите клиентскую библиотеку Supabase:

npm install @supabase/supabase-js

Настройка клиента Supabase

В каталоге src создайте utils/SupabaseClient.js и добавьте:

import { createClient } from '@supabase/supabase-js';   
const supabaseURL = process.env.REACT_APP_SUPABASE_URL;  
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY;  
export const supabase = createClient(supabaseURL, supabaseAnonKey);

Этот код создаёт экземпляр клиента Supabase. Он использует URL и публичный anon-ключ. Через этот объект React будет выполнять запросы к базе.

Ссылка: можно хранить ключи в система CI/CD или secrets при деплое. Для локальной разработки .env достаточно.

Реализация CRUD в React

Ниже показан полный пошаговый пример добавления, чтения, обновления и удаления записей.

1. Добавление данных

Откройте src/App.js, удалите boilerplate и вставьте следующий код (фрагмент):

import { useState, useEffect } from 'react';  
import ProductCard from './components/ProductCard';  
import { supabase } from './utils/SupabaseClient';  
import './App.css';  
  
export default function App() {  
  const [name, setName] = useState('');  
  const [description, setDescription] = useState('');  
  
  async function addProduct() {  
    try {  
      const { data, error } = await supabase  
        .from('products')  
        .insert({  
          name: name,  
          description: description  
        })  
        .single();  
  
      if (error) throw error;  
      window.location.reload();  
    } catch (error) {  
      alert(error.message);  
    }  
  }

Объяснение: функция addProduct вставляет новую строчку в таблицу products. После успешной вставки выполняется перезагрузка страницы, чтобы обновить список записей. В продакшне лучше обновлять состояние локально вместо перезагрузки.

2. Чтение данных

Добавьте обработчик получения списка продуктов:

  const [products, setProducts] = useState([]);  
  
  async function getProducts() {  
    try {  
      const { data, error } = await supabase  
        .from('products')  
        .select('*')  
        .limit(10);  
  
      if (error) throw error;  
  
      if (data != null) {  
        setProducts(data);  
      }  
    } catch (error) {  
      alert(error.message);  
    }  
  }  
  
  useEffect(() => {  
    getProducts();  
  }, []);

useEffect вызывает getProducts при монтировании компонента. Метод select(‘*’) получает все поля, limit(10) ограничивает результат.

Далее рендерим форму добавления и список продуктов:

  return (  
    <>  
      

Store Products

Add products Data to the Supabase Database

setName(e.target.value)} /> setDescription(e.target.value)} />

Current Products in the Database

{products.map((product) => (
))}
); }

Совет: вместо window.location.reload() обновляйте состояние с помощью setProducts, это быстрее и даёт лучший UX.

3. Обновление и удаление

Создайте components/ProductCard.js и добавьте следующий код:

import { useState } from 'react';  
import { supabase } from '../utils/SupabaseClient';  
import './productcard.styles.css';  
  
export default function ProductCard(props) {  
  const product = props.product;  
  const [editing, setEditing] = useState(false);  
  const [name, setName] = useState(product.name);  
  const [description, setDescription] = useState(product.description);  
  
  return (  
    
{editing === false ? (
{product.name}

{product.description}

) : (

Editing Product


setName(e.target.value)}/> setDescription(e.target.value)}/>
)}
); }

Добавьте функции updateProduct и deleteProduct ниже объявления состояний в том же файле:

async function updateProduct() {  
  try {  
    const { data, error } = await supabase  
      .from('products')  
      .update({  
        name: name,  
        description: description  
      })  
      .eq('id', product.id);  
  
    if (error) throw error;  
    window.location.reload();  
  } catch (error) {  
    alert(error.message);  
  }  
}

async function deleteProduct() {  
  try {  
    const { data, error } = await supabase  
      .from('products')  
      .delete()  
      .eq('id', product.id);  
    if (error) throw error;  
    window.location.reload();  
  } catch (error) {  
    alert(error.message);  
  }  
}

Примечание: для улучшенного UX лучше обновлять локальное состояние и показывать подтверждение удаления вместо немедленной перезагрузки.

Когда такой подход не подходит

  • Большой объём транзакционной логики на сервере. Если бизнес-логика сложная — лучше выделить бэкенд API.
  • Особые требования к масштабированию и оптимизации запросов. BaaS накладывает ограничения по тонкой настройке.
  • Строгие нормативные требования к хранению данных или разграничению доступа, которые нельзя реализовать на уровне клиента.

Если попадаете в один из этих сценариев, рассматривайте выделенный бэкенд или использование серверных функций (edge functions).

Альтернативные подходы

  • Использовать Firebase (Firestore) — схожая модель BaaS с другим набором возможностей.
  • Построить REST/GraphQL API на Node.js/Express или на Go/Python и хранить данные в PostgreSQL напрямую.
  • Использовать серверныеless-функции (Vercel, Netlify) между клиентом и базой для дополнительного контроля и скрытия ключей.

Ментальные модели и эвристики

  • Разделяй ответственность: клиент отвечает за UI и валидацию, сервер — за целостность и бизнес-правила.
  • Принцип наименьших привилегий: давайте ключи с минимальными правами для публичного использования.
  • Локальное состояние как источник правды: обновляйте UI через state, а не через перезагрузку страницы.

Факт-бокс: ключевые числа и рекомендации

  • Подходит для: MVP, внутренних инструментов, прототипов.
  • Рекомендация лимита выборки: по умолчанию ставьте limit и пагинацию (например, 10–50 записей за запрос).
  • Безопасность: не храните секреты в исходниках; используйте serverless/edge для приватных операций.

Чек-лист ролей при разработке

  • Разработчик фронтенда:
    • Настроить .env и supabase клиент.
    • Реализовать CRUD-логику и локальное обновление состояния.
    • Добавить обработку ошибок и loading-индикаторы.
  • Разработчик бэкенда / DevOps:
    • Настроить правила RLS (Row Level Security) в Supabase при необходимости.
    • Настроить резервное копирование и мониторинг.
  • Инженер по безопасности:
    • Проверить права anon-ключа.
    • Настроить аудит доступа и логирование.
  • Тестировщик:
    • Покрыть сценарии: создание, чтение, обновление, удаление, ошибки валидации.

Критерии приёмки

  • Создание: новая запись появляется в UI без дублирования.
  • Чтение: список загружается и корректно отображает поля.
  • Обновление: изменения сохраняются в базе и видны в UI.
  • Удаление: запись удаляется и отсутствует в списке.
  • Обработка ошибок: пользователь видит понятное сообщение при ошибке сети или валидации.

Шпаргалка и сниппеты

  • Установка клиента:
npm install @supabase/supabase-js
  • Инициализация клиента (utils/SupabaseClient.js):
import { createClient } from '@supabase/supabase-js';
const supabaseURL = process.env.REACT_APP_SUPABASE_URL;
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseURL, supabaseAnonKey);
  • Пример запроса на выборку с пагинацией:
const { data, error } = await supabase
  .from('products')
  .select('*')
  .range(0, 49); // первые 50 записей
  • Пример обновления конкретной записи:
const { data, error } = await supabase
  .from('products')
  .update({ name: 'Новое имя' })
  .eq('id', 123);

Безопасность и конфиденциальность

  • Никогда не храните приватные ключи в клиентском коде. Используйте серверный слой или функции для операций, требующих elevated прав.
  • Используйте Row Level Security (RLS) в Supabase для контроля доступа к строкам таблиц.
  • Логируйте операции и настройки прав доступа. Это поможет расследовать инциденты.
  • Если вы работаете с персональными данными, выполните соответствие требованиям GDPR/локального законодательства: хранение, право на удаление и экспорт данных.

Важно: anon-ключ предоставляет публичный доступ с разрешениями, заданными в политике Supabase. Настройте правила безопасности до выхода в продакшен.

Тестирование: кейсы и приёмка

  • Проверить создание продукта с пустыми и некорректными полями.
  • Проверить отображение списка при пустой базе.
  • Проверить корректность обновления и отмены изменений.
  • Проверить удаление и откат действий пользователя.
  • Тестировать при плохом соединении и симулировать ошибки API.

Миграции и совместимость

  • Для изменений схемы используйте SQL-скрипты в SQL Editor или систему миграций (например, через миграции в репозитории).
  • При изменении полей аккуратно обновляйте клиентские формы и проверяйте backward-совместимость для старых записей.

Быстрый roadmap роста приложения

  1. MVP: клиентский CRUD с anon-ключом и простыми правилами.
  2. RLS и аутентификация: добавьте аутентификацию пользователей и правила доступа.
  3. Серверные функции: вынесите чувствительные операции в серверныеless-функции.
  4. Мониторинг и резервное копирование: настройте бэкапы и алерты.

Краткое резюме

Supabase позволяет быстро реализовать CRUD-приложение на React без отдельного бэкенда. Подходит для MVP и внутренних инструментов. Для продакшена обязательно настроить безопасность, RLS и миграции схемы.

Важно: используйте локальное обновление состояния вместо перезагрузки страницы для лучшего UX и меньшей нагрузки на сеть.

Ресурсы для дальнейшего изучения

  • Документация Supabase: https://supabase.com/docs
  • Больше примеров и шаблонов можно найти в официальном репозитории и сообществе Supabase.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство