Creating a React Toggle Based on Database Value

Introduction

Managing state in React applications can sometimes feel like a daunting task, especially when we’re dealing with dynamic data fetched from a database. One common use case developers encounter is the need to toggle a component’s state based on a value retrieved from a database. In this tutorial, we’ll explore how to implement a React toggle switch that reflects database values seamlessly. This will aid in enhancing user experience by ensuring that the application state remains consistent with the data source.

We’ll be using React hooks, particularly useState and useEffect, to manage the toggle state and handle the fetching of data from an API. Our example will involve a toggle button for a setting (e.g., notifications) that the user can turn on or off. The initial state of the toggle will be determined by a value stored in a database which is fetched through a simulated API call. Let’s dive into the implementation!

Setting Up the React Environment

Before we start coding, ensure you have a React environment set up. You can use Create React App, a commonly used tool for bootstrapping new React applications. If you haven’t already set it up, you can do so by running:

npx create-react-app toggle-example
cd toggle-example
npm start

This will create a new directory called toggle-example and start your React application. Once the setup is complete, we can begin adding our toggle component.

Creating the Toggle Component

First, let’s create a new component called ToggleSwitch. This component will handle the toggle state and the API call. Create a new file named ToggleSwitch.js in the src directory. Here’s how the component structure will look:

import React, { useState, useEffect } from 'react';

const ToggleSwitch = () => {
    const [isToggled, setIsToggled] = useState(false);

    // Fetch initial state from the database (simulated)
    useEffect(() => {
        fetchToggleState();
    }, []);

    const fetchToggleState = async () => {
        // Simulated fetching from a database
        const response = await fetch('/api/toggle-state');
        const data = await response.json();
        setIsToggled(data.isToggled);
    };

    const handleToggle = () => {
        setIsToggled(prevState => !prevState);
        // Here you'd also call a function to update the DB
    };

    return (
        
); }; export default ToggleSwitch;

In this code, we set up a local state isToggled that defaults to false. In the useEffect hook, we simulate fetching the toggle state from the database when the component mounts. This helps us establish the initial state of our toggle switch based on the database value.

Simulating the Database API

For the purpose of this example, we will simulate the database retrieval with a mock API. To do this, we’ll create a very simple backend using Express. If you have not already installed Express in your project, first do so by running:

npm install express

Now, create a new directory named server in the root of your project. Inside server, create a file named server.js, where we will set up our mock API:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;

app.use(express.json());
app.get('/api/toggle-state', (req, res) => {
    // Simulating a database value
    res.json({ isToggled: true }); // Change this based on your needs
});

app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

This simple express server has one endpoint: /api/toggle-state, which responds with a JSON object containing the toggle state. You can modify this value to simulate different states directly from your database.

Connecting Frontend with Backend API

Next, we need to connect our frontend React application to this backend API. Update your npm scripts in the root package.json file to include a simultaneous run of both the React app and the Express server. Install the required package by running:

npm install concurrently

Then, modify the scripts section like this:

"scripts": {
    "start": "concurrently \n    "npm run server" "npm run client",
    "client": "react-scripts start",
    "server": "node server/server.js"
}

Finally, you can start both the React app and Express server with the command: npm start. Once running, your ToggleSwitch component should now be able to fetch and display the toggle state dynamically based on the simulated database value.

Updating the Database on Toggle Change

It’s often more than just displaying the state; we also want to ensure that the toggle interacts with our backend effectively. In the handleToggle function we defined earlier, we can also add functionality to update our mock database. Let’s add a POST call to update the toggle state when the user toggles the switch:

const updateToggleState = async (newValue) => {
    await fetch('/api/toggle-state', {
        method: 'POST',
        body: JSON.stringify({ isToggled: newValue }),
        headers: { 'Content-Type': 'application/json' },
    });
};

const handleToggle = () => {
    const newToggleState = !isToggled;
    setIsToggled(newToggleState);
    updateToggleState(newToggleState); // Update the database
};

In this update, updateToggleState function sends the new toggle state to the backend. When the toggle is changed, we call this function with the updated state. This will help keep our database in sync with the user’s action on the UI.

Styling the Toggle Component

While functionality is critical, aesthetics also play an important role in user experience. To style our toggle component, we will add some custom CSS. Create a new CSS file named ToggleSwitch.css in the src folder, and add the following styles:

.toggle-switch {
    display: flex;
    align-items: center;
}

.toggle-switch input[type="checkbox"] {
    appearance: none;
    width: 50px;
    height: 24px;
    background: #ccc;
    border-radius: 50px;
    cursor: pointer;
    outline: none;
    position: relative;
}

.toggle-switch input:checked {
    background: #4caf50;
}

.toggle-switch input::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    width: 20px;
    height: 20px;
    background: white;
    border-radius: 50%;
    transition: 0.3s;
}

.toggle-switch input:checked::before {
    transform: translateX(26px);
}

Now include this CSS file in your ToggleSwitch.js file:

import './ToggleSwitch.css';

Modify the JSX in the toggle component to add a class for styling:

return (
    
);

Your toggle button should now have a much more polished look!

Testing the Toggle Component

Testing is an essential aspect of any application. For our toggle functionality, we can create unit tests that ensure the component works as intended. We’ll use Jest and React Testing Library for the testing process. If you need to install these, you can use:

npm install --save-dev @testing-library/react @testing-library/jest-dom

Create a new file ToggleSwitch.test.js in the same directory as your component.

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import ToggleSwitch from './ToggleSwitch';

test('renders toggle switch', () => {
    render();
    const toggle = screen.getByRole('checkbox');
    expect(toggle).toBeInTheDocument();
});

test('toggles state on click', () => {
    render();
    const toggle = screen.getByRole('checkbox');
    fireEvent.click(toggle);
    expect(toggle).not.toBeChecked(); // Ensure toggle functionality works
});

In these tests, we render the ToggleSwitch component, check for its existence, and simulate a click event to verify that it toggles correctly. Testing ensures reliability in your code and can prevent future bugs with changes.

Conclusion

In this tutorial, we explored how to create a React toggle component that interacts dynamically with values stored in a database. By following the steps outlined, you have created a functional toggle switch that fetches its initial state from a backend API and updates that state based on user interaction. This is a crucial skill for modern web development, especially when managing UI states that depend on external data sources.

Don’t forget to enhance your toggle switch with more styles or even animations to provide a better user experience. As you continue to build more complex web applications, the ability to manage state efficiently and interact with backend data sources will be invaluable.

Finally, I encourage you to explore further by implementing additional features, such as user authentication, or integrating it into a larger application context. This is just the beginning of your journey into building dynamic and interactive web applications with React!

Scroll to Top