/** * Redux Toolkit Demo Page * Demonstrates Redux patterns with Redux Toolkit */ import { useState } from 'react'; import { Link } from 'react-router-dom'; import { useAppDispatch, useAppSelector } from '@/store'; import { selectTodosFilter, selectTodoStats, selectFilteredTodos, setFilter, } from '@/store/slices/todosSlice'; import { selectTheme, selectResolvedTheme, selectSidebarCollapsed, setTheme, toggleSidebar, addNotification, removeNotification, selectNotifications, } from '@/store/slices/uiSlice'; export default function ReduxDemo() { const dispatch = useAppDispatch(); // Todos slice selectors const filter = useAppSelector(selectTodosFilter); const stats = useAppSelector(selectTodoStats); const filteredTodos = useAppSelector(selectFilteredTodos); // UI slice selectors const theme = useAppSelector(selectTheme); const resolvedTheme = useAppSelector(selectResolvedTheme); const sidebarCollapsed = useAppSelector(selectSidebarCollapsed); const notifications = useAppSelector(selectNotifications); const [notificationText, setNotificationText] = useState(''); const handleAddNotification = () => { if (!notificationText.trim()) return; dispatch(addNotification({ type: 'info', title: 'Notification', message: notificationText, })); setNotificationText(''); }; return (
← Back to Home

Redux Toolkit Demo

Global state management with slices, thunks, and selectors.

{/* Current State */}

Current Redux State

Theme
{theme} ({resolvedTheme})
Sidebar
{sidebarCollapsed ? 'Collapsed' : 'Expanded'}
Todo Filter
{filter}
Notifications
{notifications.length}
{/* UI Slice Actions */}

UI Slice Actions

{(['light', 'dark', 'system'] as const).map((t) => ( ))}
setNotificationText(e.target.value)} placeholder="Notification message..." className="input flex-1" />
{notifications.length > 0 && (
{notifications.map((n) => (
{n.message}
))}
)}
{/* Todos Slice */}

Todos Slice State

{(['all', 'active', 'completed'] as const).map((f) => ( ))}
Showing {filteredTodos.length} of {stats.total} todos
{/* Code Examples */}

Code Examples

Creating a Slice

{`import { createSlice, PayloadAction } from '@reduxjs/toolkit';

const uiSlice = createSlice({
  name: 'ui',
  initialState: {
    theme: 'system' as 'light' | 'dark' | 'system',
    sidebarCollapsed: false,
  },
  reducers: {
    setTheme: (state, action: PayloadAction<'light' | 'dark' | 'system'>) => {
      state.theme = action.payload;
    },
    toggleSidebar: (state) => {
      state.sidebarCollapsed = !state.sidebarCollapsed;
    },
  },
});

export const { setTheme, toggleSidebar } = uiSlice.actions;`}
              

Async Thunks

{`import { createAsyncThunk } from '@reduxjs/toolkit';

export const fetchTodos = createAsyncThunk(
  'todos/fetchTodos',
  async (_, { rejectWithValue }) => {
    try {
      const { data, error } = await supabase
        .from('todos')
        .select('*');
      if (error) throw error;
      return data;
    } catch (error) {
      return rejectWithValue(error.message);
    }
  }
);`}
              

Selectors

{`// Simple selector
export const selectTheme = (state: RootState) => state.ui.theme;

// Memoized selector with reselect
export const selectFilteredTodos = createSelector(
  [selectTodos, selectTodosFilter],
  (todos, filter) => {
    switch (filter) {
      case 'active': return todos.filter(t => !t.completed);
      case 'completed': return todos.filter(t => t.completed);
      default: return todos;
    }
  }
);`}
              

Using in Components

{`import { useAppDispatch, useAppSelector } from '@/store';

function MyComponent() {
  const dispatch = useAppDispatch();
  const theme = useAppSelector(selectTheme);

  return (
    
  );
}`}
              
); }