React Cancel Button: 5 Methods with Examples

In my decade-plus experience as a developer, I’ve found that handling cancellation actions effectively is crucial for creating user-friendly React applications. Whether you’re building forms, modals, or API requests, a well-implemented cancel button improves user experience significantly.

In this tutorial, I will walk you through different methods to implement cancel buttons in React applications. These approaches range from simple UI cancellations to more complex scenarios involving API request cancellation.

Let’s get started..

Method 1: Basic Cancel Button for Forms

The most common use case for cancel buttons is in forms where users need the option to discard their inputs.

Here’s a simple implementation:

import React, { useState } from 'react';

function UserForm({ onSubmit, onCancel }) {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    onSubmit({ name, email });
  };

  const handleCancel = () => {
    // Clear form data
    setName('');
    setEmail('');

    // Call the onCancel prop if provided
    if (onCancel) onCancel();
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Name:</label>
        <input 
          type="text" 
          value={name} 
          onChange={(e) => setName(e.target.value)} 
        />
      </div>
      <div>
        <label>Email:</label>
        <input 
          type="email" 
          value={email} 
          onChange={(e) => setEmail(e.target.value)} 
        />
      </div>
      <div>
        <button type="submit">Submit</button>
        <button type="button" onClick={handleCancel}>Cancel</button>
      </div>
    </form>
  );
}

You can see the output in the screenshot below.

React js Cancel Button for Forms

In this example, our cancel button:

  • Uses type="button" to prevent form submission
  • Clears form data
  • Triggers an optional callback function

Read How to Handle Events in React JS

Method 2: Cancel Button with React Router

When working with multi-page forms or workflows, you might want to navigate away when a user cancels. React Router makes this easy:

If you haven’t installed React Router, run this in your terminal:

npm install react-router-dom
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';

function RegistrationForm() {
  const [formData, setFormData] = useState({
    firstName: '',
    lastName: '',
    email: ''
  });

  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();
    // Process form submission
    console.log('Form submitted:', formData);
    navigate('/success');
  };

  const handleCancel = () => {
    // Confirm before navigating away
    if (window.confirm('Are you sure you want to cancel? Your data will be lost.')) {
      navigate('/home');
    }
  };

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prevData => ({
      ...prevData,
      [name]: value
    }));
  };

  return (
    <form onSubmit={handleSubmit}>
      <h2>Create Account</h2>
      {/* Form fields */}
      <div>
        <label>First Name:</label>
        <input 
          type="text" 
          name="firstName" 
          value={formData.firstName} 
          onChange={handleChange} 
        />
      </div>
      <div>
        <label>Last Name:</label>
        <input 
          type="text" 
          name="lastName" 
          value={formData.lastName} 
          onChange={handleChange} 
        />
      </div>
      <div>
        <label>Email:</label>
        <input 
          type="email" 
          name="email" 
          value={formData.email} 
          onChange={handleChange} 
        />
      </div>
      <div>
        <button type="submit">Create Account</button>
        <button type="button" onClick={handleCancel}>Cancel</button>
      </div>
    </form>
  );
}

Write this code in the index.js file:

import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import './index.css'; // optional, for styling

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

You can see the output in the screenshot below.

React js Cancel Button with React Router

This is the output you will get when you press the create account button.

React js Cancel Button with React Router success

This is the output you will get when you press the cancel button.

React js Cancel Button with React Router cancel

This implementation adds a confirmation dialog to prevent accidental data loss, which is particularly important for longer forms.

Method 3: Modal Cancel Button

Modals are perfect for focused tasks, and a cancel button is essential for closing them:

import React, { useState } from 'react';
import './Modal.css';

function Modal({ isOpen, onClose, onSubmit, title }) {
  const [input, setInput] = useState('');

  if (!isOpen) return null;

  const handleSubmit = (e) => {
    e.preventDefault();
    onSubmit(input);
    setInput('');
  };

  const handleCancel = () => {
    setInput('');
    onClose();
  };

  return (
    <div className="modal-overlay">
      <div className="modal-content">
        <h2>{title}</h2>
        <form onSubmit={handleSubmit}>
          <input 
            type="text" 
            value={input} 
            onChange={(e) => setInput(e.target.value)} 
            placeholder="Enter your data"
          />
          <div className="modal-buttons">
            <button type="submit">Submit</button>
            <button type="button" onClick={handleCancel}>Cancel</button>
          </div>
        </form>
      </div>
    </div>
  );
}

// Usage in a parent component
function App() {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [result, setResult] = useState('');

  const handleSubmit = (data) => {
    setResult(data);
    setIsModalOpen(false);
  };

  return (
    <div className="app">
      <h1>Modal Example</h1>
      <button onClick={() => setIsModalOpen(true)}>Open Modal</button>
      {result && <p>You submitted: {result}</p>}

      <Modal 
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        onSubmit={handleSubmit}
        title="Enter Information"
      />
    </div>
  );
}

This modal implementation includes a cancel button that closes the modal and resets any input, providing a clean slate for the next interaction.

Method 4: Cancel API Requests with Axios

One of the most powerful cancel button implementations is for API requests. Here’s how to do it with Axios:

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

function SearchComponent() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const searchUsers = async (searchQuery) => {
    setLoading(true);
    setError(null);

    // Create a cancel token
    const cancelToken = axios.CancelToken.source();

    try {
      const response = await axios.get(
        `https://api.github.com/search/users?q=${searchQuery}`,
        { cancelToken: cancelToken.token }
      );

      setResults(response.data.items);
      setLoading(false);
      return cancelToken;
    } catch (error) {
      if (axios.isCancel(error)) {
        console.log('Request canceled:', error.message);
      } else {
        setError('Error fetching data. Please try again.');
        setLoading(false);
      }
      return cancelToken;
    }
  };

  const handleSearch = (e) => {
    e.preventDefault();
    if (query.trim()) {
      searchUsers(query);
    }
  };

  const handleCancel = (cancelTokenSource) => {
    if (cancelTokenSource) {
      cancelTokenSource.cancel('User canceled the request');
      setLoading(false);
    }
  };

  return (
    <div>
      <h2>GitHub User Search</h2>
      <form onSubmit={handleSearch}>
        <input
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="Search GitHub users..."
        />
        <button type="submit">Search</button>
        {loading && (
          <button 
            type="button" 
            onClick={() => handleCancel(searchUsers.cancelToken)}
          >
            Cancel
          </button>
        )}
      </form>

      {loading && <p>Loading...</p>}
      {error && <p className="error">{error}</p>}

      <ul>
        {results.map(user => (
          <li key={user.id}>{user.login}</li>
        ))}
      </ul>
    </div>
  );
}

This implementation is particularly useful for search interfaces where users might want to cancel a request if they change their mind or make a typo.

Method 5: Use AbortController for Fetch API

If you’re using the native Fetch API instead of Axios, you can implement cancellation with AbortController:

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

function DataFetcher() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const abortControllerRef = useRef(null);

  const fetchData = async () => {
    // Reset states
    setLoading(true);
    setError(null);
    setData(null);

    // Create a new AbortController
    abortControllerRef.current = new AbortController();
    const { signal } = abortControllerRef.current;

    try {
      // This example uses the US Census API
      const response = await fetch(
        'https://api.census.gov/data/2020/acs/acs5?get=NAME,B01001_001E&for=state:*', 
        { signal }
      );

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      const result = await response.json();
      setData(result);
      setLoading(false);
    } catch (err) {
      if (err.name === 'AbortError') {
        console.log('Fetch aborted');
      } else {
        setError('Error fetching data: ' + err.message);
      }
      setLoading(false);
    }
  };

  const handleCancel = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      setLoading(false);
    }
  };

  return (
    <div>
      <h2>US State Population Data</h2>
      <div>
        <button onClick={fetchData} disabled={loading}>
          Fetch Data
        </button>
        {loading && (
          <button onClick={handleCancel}>
            Cancel
          </button>
        )}
      </div>

      {loading && <p>Loading...</p>}
      {error && <p className="error">{error}</p>}

      {data && (
        <div>
          <h3>State Populations:</h3>
          <ul>
            {data.slice(1).map((state, index) => (
              <li key={index}>
                {state[0]}: {parseInt(state[1]).toLocaleString()} people
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

This example fetches US Census data and allows users to cancel the request if it’s taking too long.

Styling Cancel Buttons for Better UX

The visual design of cancel buttons is crucial for user experience. A common pattern is to make cancel buttons visually distinct from primary action buttons to prevent accidental clicks. Here’s how I style cancel buttons in my React projects:

import React from 'react';
import './Button.css';

function ActionButtons({ onSubmit, onCancel }) {
  return (
    <div className="button-container">
      <button 
        className="button primary-button" 
        onClick={onSubmit}
      >
        Submit
      </button>
      <button 
        className="button cancel-button" 
        onClick={onCancel}
      >
        Cancel
      </button>
    </div>
  );
}

And the corresponding CSS:

.button-container {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}

.button {
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.primary-button {
  background-color: #0066cc;
  color: white;
  border: 1px solid #0066cc;
}

.primary-button:hover {
  background-color: #0052a3;
}

.cancel-button {
  background-color: white;
  color: #333;
  border: 1px solid #ccc;
}

.cancel-button:hover {
  background-color: #f1f1f1;
}

This styling approach makes the cancel button less prominent while still accessible, reducing the chances of users accidentally discarding their work.

Implementing effective cancel buttons in React applications is more than just adding a button element. It requires thoughtful handling of various states, resources, and user expectations.

Related tutorials:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.