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​