Skip to content

Instantly share code, notes, and snippets.

@JamalLyons
Last active October 27, 2023 17:35
Show Gist options
  • Save JamalLyons/f19dbeb0ebeff66742f4dfbaae5053f1 to your computer and use it in GitHub Desktop.
Save JamalLyons/f19dbeb0ebeff66742f4dfbaae5053f1 to your computer and use it in GitHub Desktop.
The best React Database? ConvexDB Introduction

Convex x React

Convex is a Backend Application Platform that keeps you focused on building your product. Convex Functions, Database, File Storage, Scheduling, and Search fit together cohesively, and are accessible from client libraries for your favorite environment. Everything in Convex is live and realtime.

Features

  • Backend API
  • First class React Integration
  • Mix of Relational and NoSQL

install deps

pnpm create vite

pnpm add convex

pnpm convex dev

Main.tsx

import { StrictMode } from 'react';
import ReactDOM from 'react-dom/client';
import { ConvexProvider, ConvexReactClient } from 'convex/react';

import './App.css';
import App from './App';

const address = import.meta.env.VITE_CONVEX_URL;

const convex = new ConvexReactClient(address);

ReactDOM.createRoot(document.getElementById('root')!).render(
	<StrictMode>
		<ConvexProvider client={convex}>
			<App />
		</ConvexProvider>
	</StrictMode>
);

Schema

import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
   messages: defineTable({
      author: v.string(),
      body: v.string()
   })
})

Message Functions

// convex/messages.ts
import { v } from "convex/values";
import { query, mutation } from "./_generated/server";

export const list = query(async (ctx) => {
  return await ctx.db.query("messages").collect();
});

export const send = mutation({
  args: { body: v.string(), author: v.string() },
  handler: async (ctx, { body, author }) => {
    const message = { body, author };
    await ctx.db.insert("messages", message);
  },
});

App.tsx

import { FormEvent, useState } from "react";
import { useMutation, useQuery } from "convex/react";
import { api } from "../convex/_generated/api";

export default function App() {
  const messages = useQuery(api.messages.list) || [];

  const [newMessageText, setNewMessageText] = useState("");
  const sendMessage = useMutation(api.messages.send);

  const [name] = useState(() => "User " + Math.floor(Math.random() * 10000));
  async function handleSendMessage(event: FormEvent) {
    event.preventDefault();
    await sendMessage({ body: newMessageText, author: name });
    setNewMessageText("");
  }
  return (
    <main>
      <h1>Convex Chat</h1>
      <p className="badge">
        <span>{name}</span>
      </p>
      <ul>
        {messages.map((message) => (
          <li key={message._id}>
            <span>{message.author}:</span>
            <span>{message.body}</span>
            <span>{new Date(message._creationTime).toLocaleTimeString()}</span>
          </li>
        ))}
      </ul>
      <form onSubmit={handleSendMessage}>
        <input
          value={newMessageText}
          onChange={(event) => setNewMessageText(event.target.value)}
          placeholder="Write a message…"
        />
        <input type="submit" value="Send" disabled={!newMessageText} />
      </form>
    </main>
  );
}

CSS

Copy from here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment