Skip to main content

Redux Adapter

Seamlessly integrate React Dev Debugger with your Redux store for comprehensive action and state tracking.

Installation

The Redux adapter is included in the main package:

npm install react-dev-debugger

Basic Setup

Import and configure the Redux adapter in your store setup:

store.ts
import { createStore } from 'redux';
import { createReduxAdapter } from 'react-dev-debugger/adapters/redux';

// Your root reducer
const rootReducer = (state, action) => {
// ... reducer logic
};

// Create the store
const store = createStore(rootReducer);

// Connect the debugger adapter
createReduxAdapter(store, {
name: 'Redux Store',
trackActions: true,
trackState: true,
});

export default store;

Live Playground

Redux Store Interaction

Counter Actions
Count: 0
Todo Actions
Todos: 0
Current State
{
  "count": 0,
  "todos": []
}
Adapter Configuration
import { createReduxAdapter } from 
  'react-dev-debugger/adapters/redux';

const store = createStore(reducer);

createReduxAdapter(store, {
  name: 'Redux Store',
  trackActions: true,
  trackState: true,
});

Action Timeline

No actions dispatched yet. Interact with the components above.

Redux Adapter Features:

  • Track all dispatched actions
  • Monitor state changes
  • View action payloads
  • Time-travel debugging
  • Action replay

With Redux Toolkit

If you're using Redux Toolkit, the setup is even cleaner:

store.ts
import { configureStore } from '@reduxjs/toolkit';
import { createReduxAdapter } from 'react-dev-debugger/adapters/redux';
import todosReducer from './features/todos/todosSlice';
import userReducer from './features/user/userSlice';

export const store = configureStore({
reducer: {
todos: todosReducer,
user: userReducer,
},
});

// Connect debugger
createReduxAdapter(store, {
name: 'App Store',
maxSnapshots: 50, // Limit history for performance
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Configuration Options

interface ReduxAdapterOptions {
// Display name in the debugger
name?: string;

// Track all dispatched actions
trackActions?: boolean;

// Track state changes
trackState?: boolean;

// Maximum number of snapshots to keep
maxSnapshots?: number;

// Filter which actions to track
actionFilter?: (action: any) => boolean;

// Transform state before displaying
stateTransform?: (state: any) => any;
}

Advanced Example

store.ts
import { configureStore } from '@reduxjs/toolkit';
import { createReduxAdapter } from 'react-dev-debugger/adapters/redux';

export const store = configureStore({
reducer: {
// ... your reducers
},
});

// Advanced configuration
createReduxAdapter(store, {
name: 'My App Store',
trackActions: true,
trackState: true,
maxSnapshots: 100,

// Only track specific actions
actionFilter: (action) => {
// Ignore frequent polling actions
return !action.type.startsWith('polling/');
},

// Hide sensitive data
stateTransform: (state) => ({
...state,
user: {
...state.user,
password: '[REDACTED]',
apiKey: '[REDACTED]',
},
}),
});

Viewing Redux Actions

Once connected, all Redux actions appear in the debugger timeline:

  1. Open the debugger panel (Ctrl/Cmd + Shift + D)
  2. Switch to the Timeline tab
  3. See each dispatched action with:
    • Action type
    • Payload
    • State before/after
    • Timestamp

Complete Example

App.tsx
import { Provider } from 'react-redux';
import { store } from './store';
import 'react-dev-debugger/dev';

// Features
import TodoList from './features/todos/TodoList';
import UserProfile from './features/user/UserProfile';

function App() {
return (
<Provider store={store}>
<div className="App">
<UserProfile />
<TodoList />
</div>
</Provider>
);
}

export default App;
features/todos/todosSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface Todo {
id: number;
text: string;
completed: boolean;
}

interface TodosState {
items: Todo[];
filter: 'all' | 'active' | 'completed';
}

const initialState: TodosState = {
items: [],
filter: 'all',
};

const todosSlice = createSlice({
name: 'todos',
initialState,
reducers: {
addTodo: (state, action: PayloadAction<string>) => {
state.items.push({
id: Date.now(),
text: action.payload,
completed: false,
});
},
toggleTodo: (state, action: PayloadAction<number>) => {
const todo = state.items.find(t => t.id === action.payload);
if (todo) {
todo.completed = !todo.completed;
}
},
setFilter: (state, action: PayloadAction<TodosState['filter']>) => {
state.filter = action.payload;
},
},
});

export const { addTodo, toggleTodo, setFilter } = todosSlice.actions;
export default todosSlice.reducer;
features/todos/TodoList.tsx
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, toggleTodo } from './todosSlice';
import type { RootState } from '../../store';

export default function TodoList() {
const todos = useSelector((state: RootState) => state.todos.items);
const dispatch = useDispatch();

const [input, setInput] = useState('');

const handleAdd = () => {
if (input.trim()) {
dispatch(addTodo(input));
setInput('');
}
};

return (
<div>
<h2>Todos</h2>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleAdd()}
/>
<button onClick={handleAdd}>Add</button>

<ul>
{todos.map(todo => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => dispatch(toggleTodo(todo.id))}
/>
{todo.text}
</li>
))}
</ul>
</div>
);
}

Debugging Tips

1. Filter Noisy Actions

Redux apps often have frequent actions (like UI updates). Filter them out:

createReduxAdapter(store, {
actionFilter: (action) => {
const ignored = ['ui/', 'router/', 'polling/'];
return !ignored.some(prefix => action.type.startsWith(prefix));
},
});

2. Simplify Complex State

If your state is very large, transform it to show only relevant parts:

createReduxAdapter(store, {
stateTransform: (state) => ({
todos: state.todos.items.length + ' items',
user: state.user.name,
// ... show summaries instead of full data
}),
});

3. Time-Travel Debugging

Use the debugger's time-travel feature to:

  1. Reproduce bugs by replaying action sequences
  2. Test different state scenarios
  3. Export and share problematic state snapshots

Best Practices

✅ Do's

  • Use descriptive action names: user/login instead of LOGIN
  • Keep action payloads serializable
  • Use the adapter in development only
  • Set reasonable maxSnapshots limits

❌ Don'ts

  • Don't track every single action in large apps
  • Don't include sensitive data in tracked state
  • Don't use in production builds
  • Don't create multiple adapter instances

Troubleshooting

Actions Not Appearing

Make sure:

  1. The adapter is created after the store
  2. trackActions: true is set
  3. The debugger panel is open
  4. Actions aren't filtered out

Performance Issues

If the app becomes slow:

  1. Reduce maxSnapshots
  2. Use actionFilter to skip frequent actions
  3. Use stateTransform to reduce state size
  4. Check for unnecessary re-renders

Next Steps