- Published on
How to setup Supabase in React ? And Some Useful Tips
- Authors
- Name
- Emin Vergil
- @eminvergil
How to Set Up Supabase in React?
Target Audience
I've aimed this article at people who want to learn about React and Supabase.
Learning Objectives
After completing this article, you will know how to do the following:
- Create a React application
- Set up Supabase
- Fetch data from Supabase
- Perform CRUD operations in Supabase
What is Supabase?
Supabase is an open-source alternative to Firebase. Start your project with a PostgreSQL database, authentication, instant APIs, real-time subscriptions, and storage.
The key difference between Firestore and Supabase is that Firestore is a NoSQL database, whereas Supabase uses a relational database.
Project Setup
You can check out the Supabase official documentation for project setup. You need to create a project in the Supabase dashboard. There are multiple setup documents for different frameworks, but in this article, I will focus on React.
Create a Project
- Go to app.supabase.com.
- Click on "New Project."
- Enter your project details.
- Wait for the new database to launch.
Building the Application
Follow these steps to build the application.
1. Create a React Application
npx create-react-app supabase-react
cd supabase-react
2. Install the Supabase JavaScript Library
npm install @supabase/supabase-js
.env
File
3. Add Environment Variables to the You can obtain these variables from the Supabase dashboard.
REACT_APP_SUPABASE_URL=YOUR_SUPABASE_URL
REACT_APP_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
4. Create the Supabase Client
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)
You can use this client for authorization, fetching, or mutating data from the database, etc.
5. Create a Service
We will create a service called dummyService
where we implement CRUD functions using Supabase operations. We can reference this service from other components to avoid code duplication in our project.
Create Function
async function Create(id, name) {
let response = await supabase // This is our client
.from('dummy')
.insert({
id: id,
name: name,
})
return response
}
As you can see, for the create operation, we use the insert operation from Supabase.
Read Function
async function Get(name) {
let response = await supabase // This is our client
.from('dummy')
.select('*')
.eq('name', name)
return response
}
Update Function
async function Update(id, name) {
let response = await supabase // This is our client
.from('dummy')
.update({ name: name })
.match({ id: id })
return response
}
Delete Function
async function Delete(id) {
let response = await supabase // This is our client
.from('dummy')
.delete()
.match({ id: id })
return response
}
We can create a service that contains these methods, and when we want to use it, we can import this service. Creating a service for a specific domain is important because it prevents code duplication in our project, making it easier to maintain as the codebase grows.
Example Use Case
import { dummyService } from ".../somewhere";
...
var item = dummyService.Get("name");
return (
<p>{item}</p>
);
...
Sometimes we want to fetch data before rendering a page. In such scenarios, we can use the useEffect
and useState
hooks in React. We can call our service functions inside the useEffect
hook, and we can create a state for the loading status of our page.
Here is an example use case:
function AnExampleComponent() {
const [loading, setLoading] = useState(true);
const [items, setItems] = useState(null);
const getDataFromService = async (name) => {
setLoading(true);
let { data } = await dummyService.Get(name);
if (data) setItems(data);
setLoading(false);
};
useEffect(() => {
getDataFromService("stuff");
}, []);
return (
...
);
}
As shown in the example, we create loading states for fetching data. This state provides information about whether the service call has completed. If we do not finish the service request, or if it takes a long time, we can display the loading state to improve user experience. We can also handle other states that may arise from our service, such as error
. If an error occurs in our service function, we can display that information in the UI if necessary.