Top Related Projects
DevTools for Redux with hot reloading, action replay, and customizable UI
Redux DevTools extension.
persist and rehydrate a redux store
Logger for Redux
Thunk middleware for Redux
A JS library for predictable global state management
Quick Overview
Redux Logger is a middleware for Redux that logs actions and state changes to the console. It provides a clear and detailed view of how your Redux store is changing over time, making it easier to debug and understand the flow of data in your application.
Pros
- Easy to set up and integrate with existing Redux applications
- Provides detailed logs of actions and state changes
- Customizable logging options (e.g., collapsed groups, colors, timestamps)
- Helps in debugging and understanding the flow of data in Redux applications
Cons
- Can clutter the console in large applications with frequent state changes
- May impact performance if used in production environments
- Requires manual removal or disabling for production builds
- Limited to console output, which may not be ideal for all debugging scenarios
Code Examples
- Basic setup:
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
import rootReducer from './reducers';
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
- Customizing logger options:
import { createLogger } from 'redux-logger';
const logger = createLogger({
collapsed: true,
colors: {
title: () => 'blue',
prevState: () => '#9E9E9E',
action: () => '#03A9F4',
nextState: () => '#4CAF50',
error: () => '#F20404',
},
});
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
- Conditional logging:
import { createLogger } from 'redux-logger';
const logger = createLogger({
predicate: (getState, action) => action.type !== 'FREQUENT_ACTION'
});
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
Getting Started
To use Redux Logger in your project, follow these steps:
-
Install the package:
npm install redux-logger
-
Import and add the middleware to your Redux store:
import { createStore, applyMiddleware } from 'redux'; import logger from 'redux-logger'; import rootReducer from './reducers'; const store = createStore( rootReducer, applyMiddleware(logger) );
-
That's it! Now you'll see detailed logs in your console for every dispatched action and state change.
Competitor Comparisons
DevTools for Redux with hot reloading, action replay, and customizable UI
Pros of redux-devtools
- Offers a more comprehensive debugging experience with time-travel debugging
- Provides a visual interface for inspecting state changes
- Supports multiple monitors and extensions for enhanced functionality
Cons of redux-devtools
- Requires additional setup and configuration
- Can be more resource-intensive, especially for large applications
- May have a steeper learning curve for beginners
Code Comparison
redux-logger:
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(reducer, applyMiddleware(logger));
redux-devtools:
import { composeWithDevTools } from 'redux-devtools-extension';
const store = createStore(reducer, composeWithDevTools(
applyMiddleware(...middleware)
));
Key Differences
- redux-logger is a simple middleware that logs actions and state changes to the console
- redux-devtools provides a more feature-rich debugging experience with a graphical interface
- redux-logger is easier to set up and use out of the box
- redux-devtools offers more advanced features like time-travel debugging and state diffing
Use Cases
- redux-logger: Quick and simple debugging, lightweight projects
- redux-devtools: Complex applications, in-depth debugging needs, visual state inspection
Redux DevTools extension.
Pros of redux-devtools-extension
- Provides a powerful browser extension for debugging Redux applications
- Offers time-travel debugging, allowing developers to step through state changes
- Supports hot reloading and persistence of debug sessions
Cons of redux-devtools-extension
- Requires installation of a browser extension, which may not be suitable for all environments
- Can be more complex to set up initially compared to redux-logger
- May have a higher performance impact on large applications
Code Comparison
redux-devtools-extension:
import { createStore, applyMiddleware, compose } from 'redux';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(...middleware)
));
redux-logger:
import { createStore, applyMiddleware } from 'redux';
import logger from 'redux-logger';
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
redux-devtools-extension offers a more comprehensive debugging experience with features like time-travel debugging and state persistence. However, it requires a browser extension and may have a steeper learning curve. redux-logger, on the other hand, is simpler to set up and doesn't require additional installations, but provides more basic logging functionality. The choice between the two depends on the specific needs of the project and the development team's preferences.
persist and rehydrate a redux store
Pros of redux-persist
- Provides state persistence across app reloads
- Offers customizable storage engines (e.g., localStorage, AsyncStorage)
- Supports selective persistence of specific parts of the state
Cons of redux-persist
- Adds complexity to the Redux setup process
- May introduce performance overhead for large state trees
- Requires additional configuration for handling migrations
Code Comparison
redux-persist:
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
redux-logger:
import { createLogger } from 'redux-logger'
const logger = createLogger()
const store = createStore(
reducer,
applyMiddleware(logger)
)
Key Differences
- Purpose: redux-persist focuses on state persistence, while redux-logger is for debugging and logging state changes
- Integration: redux-persist modifies the reducer and store setup, redux-logger is added as middleware
- Functionality: redux-persist adds data persistence features, redux-logger provides detailed console output for state changes
Use Cases
- Use redux-persist when you need to maintain state across app reloads or in offline scenarios
- Use redux-logger during development for debugging and tracking state changes in real-time
Both libraries serve different purposes and can be used together in a Redux application to enhance development experience and app functionality.
Logger for Redux
Pros of redux-logger
- Widely used and well-maintained logging middleware for Redux
- Provides detailed console output for Redux actions and state changes
- Supports customizable logging options and coloring
Cons of redux-logger
- May impact performance in large applications due to extensive logging
- Requires manual setup and configuration in Redux store
- Limited built-in features for advanced debugging scenarios
Code Comparison
redux-logger implementation:
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
Both repositories appear to be the same project, as LogRocket/redux-logger is the official repository for the redux-logger package. There is no separate repository to compare against. The provided comparison is based on the features and characteristics of the redux-logger project itself.
redux-logger is a popular middleware for Redux that helps developers track state changes and debug their applications. It offers a range of customization options and provides clear, colorized console output for Redux actions and state updates. While it's an excellent tool for development, it's important to consider its performance impact in production environments and explore alternative debugging methods for more complex scenarios.
Thunk middleware for Redux
Pros of redux-thunk
- Allows writing asynchronous action creators
- Simplifies handling of complex async logic
- Widely adopted and well-integrated with Redux ecosystem
Cons of redux-thunk
- Doesn't provide logging functionality
- Can lead to more complex action creators
- Requires additional setup for debugging async actions
Code Comparison
redux-thunk example:
const fetchUser = (id) => {
return async (dispatch) => {
dispatch(requestUser());
try {
const user = await api.fetchUser(id);
dispatch(receiveUser(user));
} catch (error) {
dispatch(fetchUserError(error));
}
};
};
redux-logger example:
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(
reducer,
applyMiddleware(logger)
);
Key Differences
redux-thunk is a middleware that allows you to write action creators that return functions instead of actions, enabling asynchronous logic in Redux. It's primarily used for handling side effects and complex async operations.
redux-logger, on the other hand, is a logging middleware that provides detailed logs of actions and state changes in the Redux store. It's mainly used for debugging and development purposes.
While redux-thunk enhances Redux's capabilities for handling async operations, redux-logger focuses on providing visibility into the Redux state and action flow. They serve different purposes and can be used together in a Redux application for both async handling and debugging.
A JS library for predictable global state management
Pros of Redux
- Core state management library with broader functionality
- Extensive ecosystem with middleware, tools, and integrations
- Widely adopted and well-documented
Cons of Redux
- Steeper learning curve and more boilerplate code
- Overkill for simple applications or small-scale state management
- Requires additional setup for logging functionality
Code Comparison
Redux (basic store setup):
import { createStore } from 'redux';
const store = createStore(rootReducer);
redux-logger (middleware setup):
import { createLogger } from 'redux-logger';
const logger = createLogger();
const store = createStore(rootReducer, applyMiddleware(logger));
Key Differences
- Redux is a complete state management solution, while redux-logger is a middleware specifically for logging Redux actions and state changes.
- Redux requires more setup and configuration, whereas redux-logger can be easily added to an existing Redux setup.
- Redux provides a foundation for complex state management, while redux-logger focuses on debugging and development tools.
Use Cases
- Choose Redux for comprehensive state management in large-scale applications.
- Use redux-logger as a complementary tool for debugging Redux applications or when detailed action logging is required.
Community and Maintenance
- Redux has a larger community and more frequent updates.
- redux-logger is a smaller, focused project with less frequent but targeted updates.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Logger for Redux
Now maintained by LogRocket!
LogRocket is a production Redux logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay Redux actions + state, network requests, console logs, and see a video of what the user saw.
For more informatiom about the future of redux-logger, check out the discussion here.
Table of contents
Install
npm i --save redux-logger
Typescript types are also available, via DefinitelyTyped:
npm i @types/redux-logger
Usage
import { applyMiddleware, createStore } from 'redux';
// Logger with default options
import logger from 'redux-logger'
const store = createStore(
reducer,
applyMiddleware(logger)
)
// Note passing middleware as the third argument requires redux@>=3.1.0
Or you can create your own logger with custom options:
import { applyMiddleware, createStore } from 'redux';
import { createLogger } from 'redux-logger'
const logger = createLogger({
// ...options
});
const store = createStore(
reducer,
applyMiddleware(logger)
);
Note: logger must be the last middleware in chain, otherwise it will log thunk and promise, not actual actions (#20).
Options
{
predicate, // if specified this function will be called before each action is processed with this middleware.
collapsed, // takes a Boolean or optionally a Function that receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if the log group should be collapsed, `false` otherwise.
duration = false: Boolean, // print the duration of each action?
timestamp = true: Boolean, // print the timestamp with each action?
level = 'log': 'log' | 'console' | 'warn' | 'error' | 'info', // console's level
colors: ColorsObject, // colors for title, prev state, action and next state: https://github.com/LogRocket/redux-logger/blob/master/src/defaults.js#L12-L18
titleFormatter, // Format the title used when logging actions.
stateTransformer, // Transform state before print. Eg. convert Immutable object to plain JSON.
actionTransformer, // Transform action before print. Eg. convert Immutable object to plain JSON.
errorTransformer, // Transform error before print. Eg. convert Immutable object to plain JSON.
logger = console: LoggerObject, // implementation of the `console` API.
logErrors = true: Boolean, // should the logger catch, log, and re-throw errors?
diff = false: Boolean, // (alpha) show diff between states?
diffPredicate // (alpha) filter function for showing states diff, similar to `predicate`
}
Options description
level (String | Function | Object)
Level of console
. warn
, error
, info
or else.
It can be a function (action: Object) => level: String
.
It can be an object with level string for: prevState
, action
, nextState
, error
It can be an object with getter functions: prevState
, action
, nextState
, error
. Useful if you want to print
message based on specific state or action. Set any of them to false
if you want to hide it.
prevState(prevState: Object) => level: String
action(action: Object) => level: String
nextState(nextState: Object) => level: String
error(error: Any, prevState: Object) => level: String
Default: log
duration (Boolean)
Print duration of each action?
Default: false
timestamp (Boolean)
Print timestamp with each action?
Default: true
colors (Object)
Object with color getter functions: title
, prevState
, action
, nextState
, error
. Useful if you want to paint
message based on specific state or action. Set any of them to false
if you want to show plain message without colors.
title(action: Object) => color: String
prevState(prevState: Object) => color: String
action(action: Object) => color: String
nextState(nextState: Object) => color: String
error(error: Any, prevState: Object) => color: String
logger (Object)
Implementation of the console
API. Useful if you are using a custom, wrapped version of console
.
Default: console
logErrors (Boolean)
Should the logger catch, log, and re-throw errors? This makes it clear which action triggered the error but makes "break on error" in dev tools harder to use, as it breaks on re-throw rather than the original throw location.
Default: true
collapsed = (getState: Function, action: Object, logEntry: Object) => Boolean
Takes a boolean or optionally a function that receives getState
function for accessing current store state and action
object as parameters. Returns true
if the log group should be collapsed, false
otherwise.
Default: false
predicate = (getState: Function, action: Object) => Boolean
If specified this function will be called before each action is processed with this middleware.
Receives getState
function for accessing current store state and action
object as parameters. Returns true
if action should be logged, false
otherwise.
Default: null
(always log)
stateTransformer = (state: Object) => state
Transform state before print. Eg. convert Immutable object to plain JSON.
Default: identity function
actionTransformer = (action: Object) => action
Transform action before print. Eg. convert Immutable object to plain JSON.
Default: identity function
errorTransformer = (error: Any) => error
Transform error before print.
Default: identity function
titleFormatter = (action: Object, time: String?, took: Number?) => title
Format the title used for each action.
Default: prints something like action @ ${time} ${action.type} (in ${took.toFixed(2)} ms)
diff (Boolean)
Show states diff.
Default: false
diffPredicate = (getState: Function, action: Object) => Boolean
Filter states diff for certain cases.
Default: undefined
Recipes
Log only in development
const middlewares = [];
if (process.env.NODE_ENV === `development`) {
const { logger } = require(`redux-logger`);
middlewares.push(logger);
}
const store = compose(applyMiddleware(...middlewares))(createStore)(reducer);
Log everything except actions with certain type
createLogger({
predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN
});
Collapse actions with certain type
createLogger({
collapsed: (getState, action) => action.type === FORM_CHANGE
});
Collapse actions that don't have errors
createLogger({
collapsed: (getState, action, logEntry) => !logEntry.error
});
Transform Immutable (without combineReducers
)
import { Iterable } from 'immutable';
const stateTransformer = (state) => {
if (Iterable.isIterable(state)) return state.toJS();
else return state;
};
const logger = createLogger({
stateTransformer,
});
Transform Immutable (with combineReducers
)
const logger = createLogger({
stateTransformer: (state) => {
let newState = {};
for (var i of Object.keys(state)) {
if (Immutable.Iterable.isIterable(state[i])) {
newState[i] = state[i].toJS();
} else {
newState[i] = state[i];
}
};
return newState;
}
});
Log batched actions
Thanks to @smashercosmo
import { createLogger } from 'redux-logger';
const actionTransformer = action => {
if (action.type === 'BATCHING_REDUCER.BATCH') {
action.payload.type = action.payload.map(next => next.type).join(' => ');
return action.payload;
}
return action;
};
const level = 'info';
const logger = {};
for (const method in console) {
if (typeof console[method] === 'function') {
logger[method] = console[method].bind(console);
}
}
logger[level] = function levelFn(...args) {
const lastArg = args.pop();
if (Array.isArray(lastArg)) {
return lastArg.forEach(item => {
console[level].apply(console, [...args, item]);
});
}
console[level].apply(console, arguments);
};
export default createLogger({
level,
actionTransformer,
logger
});
To Do
- Update eslint config to airbnb's
- Clean up code, because it's very messy, to be honest
- Write tests
- Node.js support
- React-native support
Feel free to create PR for any of those tasks!
Known issues
- Performance issues in react-native (#32)
License
MIT
Top Related Projects
DevTools for Redux with hot reloading, action replay, and customizable UI
Redux DevTools extension.
persist and rehydrate a redux store
Logger for Redux
Thunk middleware for Redux
A JS library for predictable global state management
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot