DEV Community

loading...
Cover image for A Stateful, Serverless Database in React with the useReturn hook

A Stateful, Serverless Database in React with the useReturn hook

mbagley1020 profile image Michael Bagley ・2 min read

As React developers, we often depend on the state of the UI to make specific decisions about the functionality and business logic of our applications. This functionality includes how we query the data used in a given component.

Keeping the data in a component fresh traditionally requires the use of callbacks, the useEffect hook, or other observational methods, but what if our query was a hook in itself?

Well, in that case, a given query could automatically be re-fetched whenever a stateful dependency changes. What if I also said this hook would be subscribed to any other uses of the database across your project, re-fetching a return query if an insert, update, or delete was done somewhere else that could affect our query?

Let's explore Easybase's useReturn hook which performs both of these tasks with an easy-to-use query builder to safely perform CRUD operations, in-code!

import { EasybaseProvider, useEasybase } from 'easybase-react';

export default function App() {
  return (
    <EasybaseProvider ebconfig={ebconfig}>
      <Example />
    </EasybaseProvider>
  )
}

function Example() {
  const [minRating, setMinRating] = useState(0);
  const { db, useReturn, e } = useEasybase();

  const { frame, loading } = useReturn(() => db('BOOKS')
    .return()                           // Select query
    .where(e.gt('rating', minRating))   // rating > minRating
    .limit(10),                         // Only return 10
  [minRating]);                         // Dependencies

  if (loading) return <Spinner />
  return (
    <div>
      <Input
        value={minRating}
        onChange={e => setMinRating(e.target.value)}
        title="Minimum Rating"
      />
      <div>
        {frame.map(ele => <Card {...ele} />)}
      </div>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

The Example component automatically refreshes the given query from our Easybase table in the frame variable! Two events will cause this refresh:

  1. A variable in the dependencies array changes (similar to useEffect)
  2. Another instance of db() was used to perform an operation that may affect the current query

Easybase Table:

Alt Text

Now, we can use the Card component to demonstrate how the useReturn hook subscribes to other uses of db() across the project:

function Card({ title, rating, released, _key }){
  const { db } = useEasybase();

  const deleteButtonClicked = async () => {
    await db('BOOKS').delete().where({ _key }).one();
  }

  return (
    <div>
      <button onClick={deleteButtonClicked}>Delete</button>
      <h3>Title: <b>{title}</b></h3>
      <h5>Rating: <b>{rating}</b></h5>
      <h5>Released: <b>{released}</b></h5>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Alt Text

Each element from Easybase has a persistent, unique identifier called _key which we can use to Update or Delete specific records.

Executing the deleteButtonClicked function automatically refreshes the data in the useReturn hook without callbacks! The useReturn hook is subscribed to all other uses of db() across the project that may affect the given query.


I hope this brief introduction to the useReturn hook demonstrates how easy it is to have a stateful, automatically updating database frame in our components. For a more in-depth walkthrough, check out this piece here.

Thanks for Reading!

Discussion (3)

Collapse
dilan_ozkaynak profile image
Dilan Ozkaynak

Interesting, better that than using useEffect with an async function and another state variable.

Collapse
ryanb1303 profile image
Ryan B

Nice article , is this require actual database ?

Collapse
mbagley1020 profile image
Michael Bagley Author

It uses Easybase.

Forem Open with the Forem app