# Toggles Take Immediate Effect

**MUST** · **ID:** `interactions-toggles-immediate-effect` · **Category:** interactions
**Source:** [Rauno](https://interfaces.rauno.me/)
**Interactive version:** https://ui-guides-agent-rules.netlify.app/principles/interactions-toggles-immediate-effect

> MUST: Toggles apply their change immediately — never pair a toggle with a separate Save/confirm step. If the action needs confirmation, use a checkbox + submit button instead.

Toggles should immediately take effect without requiring a confirmation or save button

Toggle switches communicate instant on/off state. Requiring a separate save button breaks this mental model and adds unnecessary friction. If a toggle needs confirmation due to destructive consequences, use a different control pattern like a checkbox with a submit button.

## Bad — do not do this

`interactions-toggles-immediate-effect-bad`

```tsx
import { useState } from 'react';

export function TogglesImmediateEffectBad() {
  const [pendingNotifications, setPendingNotifications] = useState(false);
  const [pendingDarkMode, setPendingDarkMode] = useState(false);
  const [saved, setSaved] = useState(false);

  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4 space-y-4">
        <h3 className="text-sm font-medium text-foreground">Settings</h3>
        <div className="flex items-center justify-between">
          <span className="text-sm text-foreground">Notifications</span>
          <button
            onClick={() => {
              setPendingNotifications(!pendingNotifications);
              setSaved(false);
            }}
            className={`w-10 h-6 rounded-full transition-colors relative ${
              pendingNotifications ? 'bg-primary' : 'bg-muted'
            }`}
          >
            <span
              className={`block w-4 h-4 rounded-full bg-white absolute top-1 transition-transform ${
                pendingNotifications ? 'translate-x-5' : 'translate-x-1'
              }`}
            />
          </button>
        </div>
        <div className="flex items-center justify-between">
          <span className="text-sm text-foreground">Dark Mode</span>
          <button
            onClick={() => {
              setPendingDarkMode(!pendingDarkMode);
              setSaved(false);
            }}
            className={`w-10 h-6 rounded-full transition-colors relative ${
              pendingDarkMode ? 'bg-primary' : 'bg-muted'
            }`}
          >
            <span
              className={`block w-4 h-4 rounded-full bg-white absolute top-1 transition-transform ${
                pendingDarkMode ? 'translate-x-5' : 'translate-x-1'
              }`}
            />
          </button>
        </div>
        <button
          onClick={() => setSaved(true)}
          className="w-full px-4 py-2 bg-primary text-primary-foreground rounded-lg text-sm"
        >
          {saved ? '✓ Saved' : 'Save Changes'}
        </button>
      </div>
      <p className="text-xs text-error">
        Toggles require pressing Save — adds unnecessary friction
      </p>
    </div>
  );
}
```

## Good — do this

`interactions-toggles-immediate-effect-good`

```tsx
import { useState } from 'react';

export function TogglesImmediateEffectGood() {
  const [notifications, setNotifications] = useState(true);
  const [darkMode, setDarkMode] = useState(false);

  return (
    <div className="w-full max-w-sm space-y-4">
      <div className="bg-card border border-border rounded-lg p-4 space-y-4">
        <h3 className="text-sm font-medium text-foreground">Settings</h3>
        <div className="flex items-center justify-between">
          <span className="text-sm text-foreground">Notifications</span>
          <button
            role="switch"
            aria-checked={notifications}
            onClick={() => setNotifications(!notifications)}
            className={`w-10 h-6 rounded-full transition-colors relative ${
              notifications ? 'bg-primary' : 'bg-muted'
            }`}
          >
            <span
              className={`block w-4 h-4 rounded-full bg-white absolute top-1 transition-transform ${
                notifications ? 'translate-x-5' : 'translate-x-1'
              }`}
            />
          </button>
        </div>
        <div className="flex items-center justify-between">
          <span className="text-sm text-foreground">Dark Mode</span>
          <button
            role="switch"
            aria-checked={darkMode}
            onClick={() => setDarkMode(!darkMode)}
            className={`w-10 h-6 rounded-full transition-colors relative ${
              darkMode ? 'bg-primary' : 'bg-muted'
            }`}
          >
            <span
              className={`block w-4 h-4 rounded-full bg-white absolute top-1 transition-transform ${
                darkMode ? 'translate-x-5' : 'translate-x-1'
              }`}
            />
          </button>
        </div>
      </div>
      <p className="text-xs text-success">
        Toggles take effect immediately — no save needed
      </p>
    </div>
  );
}
```

## References

- [interfaces.rauno.me](https://interfaces.rauno.me/)
