Convert Figma logo to code with AI

gajus logoredux-immutable

redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.

1,877
82
1,877
10

Top Related Projects

60,936

A JS library for predictable global state management

27,618

Simple, scalable state management.

27,641

Create the next immutable state by mutating the current one

The official, opinionated, batteries-included toolset for efficient Redux development

8,477

The Redux Framework

Quick Overview

Redux-immutable is a library that provides a seamless integration between Redux and Immutable.js. It allows developers to create a Redux store with an Immutable.js state, enabling efficient and predictable state management in React applications.

Pros

  • Seamless integration of Redux with Immutable.js
  • Improved performance due to Immutable.js's efficient data structures
  • Enhanced state immutability, reducing bugs related to unintended state mutations
  • Compatible with existing Redux ecosystem and tools

Cons

  • Learning curve for developers unfamiliar with Immutable.js
  • Potential increase in bundle size due to additional dependency
  • May require refactoring of existing Redux code to work with Immutable.js structures

Code Examples

Creating a Redux store with an Immutable.js state:

import { createStore } from 'redux';
import { combineReducers } from 'redux-immutable';
import Immutable from 'immutable';

const initialState = Immutable.Map();
const rootReducer = combineReducers({
  // Your reducers here
});

const store = createStore(rootReducer, initialState);

Accessing state in a connected component:

import { connect } from 'react-redux';

const mapStateToProps = (state) => ({
  user: state.getIn(['user', 'data']),
  isLoading: state.getIn(['user', 'isLoading']),
});

export default connect(mapStateToProps)(YourComponent);

Using Immutable.js in a reducer:

import { fromJS } from 'immutable';

const initialState = fromJS({
  data: null,
  isLoading: false,
  error: null,
});

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'FETCH_USER_REQUEST':
      return state.set('isLoading', true);
    case 'FETCH_USER_SUCCESS':
      return state.merge({
        data: action.payload,
        isLoading: false,
        error: null,
      });
    default:
      return state;
  }
};

Getting Started

  1. Install the required packages:

    npm install redux-immutable immutable
    
  2. Create your Redux store with an Immutable.js state:

    import { createStore } from 'redux';
    import { combineReducers } from 'redux-immutable';
    import Immutable from 'immutable';
    
    const initialState = Immutable.Map();
    const rootReducer = combineReducers({
      // Your reducers here
    });
    
    const store = createStore(rootReducer, initialState);
    
  3. Use Immutable.js methods to interact with the state in your reducers and components.

Competitor Comparisons

60,936

A JS library for predictable global state management

Pros of Redux

  • Widely adopted and well-maintained by the Redux team
  • Extensive ecosystem with many middleware and tools
  • Flexible and can be used with any UI library or framework

Cons of Redux

  • Requires more boilerplate code
  • Learning curve can be steeper for beginners
  • Performance can be an issue with large state trees

Code Comparison

Redux:

import { createStore } from 'redux'

const rootReducer = (state = {}, action) => {
  // Reducer logic
}

const store = createStore(rootReducer)

Redux-Immutable:

import { createStore } from 'redux'
import { combineReducers } from 'redux-immutable'
import Immutable from 'immutable'

const rootReducer = combineReducers({
  // Reducers
})

const store = createStore(rootReducer, Immutable.Map())

Key Differences

  • Redux-Immutable focuses on using Immutable.js with Redux
  • Redux-Immutable provides a custom combineReducers function
  • Redux-Immutable initializes the store with an Immutable.Map()

Use Cases

  • Redux: General-purpose state management for React applications
  • Redux-Immutable: When you want to leverage Immutable.js for performance and data integrity in Redux

Community and Support

  • Redux: Large community, frequent updates, extensive documentation
  • Redux-Immutable: Smaller community, less frequent updates, but still actively maintained
27,618

Simple, scalable state management.

Pros of MobX

  • Simpler and more intuitive API, requiring less boilerplate code
  • Automatic tracking of state changes and re-rendering of components
  • Better performance for complex state updates due to fine-grained reactivity

Cons of MobX

  • Less predictable state updates, as mutations are allowed
  • Steeper learning curve for developers used to immutable state patterns
  • Potential for overuse of observables, leading to unnecessary re-renders

Code Comparison

MobX:

import { makeObservable, observable, action } from "mobx";

class Store {
  count = 0;

  constructor() {
    makeObservable(this, {
      count: observable,
      increment: action
    });
  }

  increment() {
    this.count++;
  }
}

Redux-Immutable:

import { createStore } from 'redux';
import { fromJS } from 'immutable';

const initialState = fromJS({ count: 0 });

function reducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state.update('count', count => count + 1);
    default:
      return state;
  }
}

const store = createStore(reducer);

Redux-Immutable focuses on maintaining immutable state using Immutable.js, while MobX allows for direct mutations of observable state. MobX's approach is more concise but may lead to less predictable state management in larger applications. Redux-Immutable provides a more structured and predictable state flow, but requires more boilerplate code.

27,641

Create the next immutable state by mutating the current one

Pros of Immer

  • Simpler API with a more intuitive approach to immutability
  • Works with any data structure, not limited to Redux state
  • Can be used in various contexts beyond Redux

Cons of Immer

  • Slightly higher learning curve for developers new to the concept
  • May introduce a small performance overhead in some cases

Code Comparison

Redux-immutable:

import { fromJS } from 'immutable';
import { combineReducers } from 'redux-immutable';

const initialState = fromJS({
  todos: []
});

const rootReducer = combineReducers({
  // reducers here
});

Immer:

import produce from 'immer';

const initialState = {
  todos: []
};

const rootReducer = produce((draft, action) => {
  // modify draft directly
});

Summary

Redux-immutable is specifically designed for use with Redux and Immutable.js, providing a way to create an immutable Redux store. It's well-suited for projects already using Immutable.js.

Immer, on the other hand, offers a more flexible approach to immutability that can be used in various contexts, including Redux. It allows developers to write simpler, more intuitive code while still maintaining immutability. Immer's API is generally easier to understand and use, especially for those new to immutable state management.

While Immer may have a slight performance cost in some scenarios, its simplicity and flexibility often outweigh this drawback for many developers and projects.

The official, opinionated, batteries-included toolset for efficient Redux development

Pros of Redux Toolkit

  • Provides a comprehensive set of tools and utilities for Redux development
  • Simplifies common Redux use cases with built-in functions like createSlice
  • Includes RTK Query for efficient API calls and data fetching

Cons of Redux Toolkit

  • Larger bundle size due to additional features and dependencies
  • Steeper learning curve for developers new to Redux concepts

Code Comparison

Redux Toolkit:

import { createSlice } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: state => state + 1,
  },
})

Redux Immutable:

import { fromJS } from 'immutable'
import { combineReducers } from 'redux-immutable'

const initialState = fromJS({
  counter: 0,
})

const rootReducer = combineReducers({
  counter: (state = initialState.get('counter'), action) => {
    // reducer logic
  },
})

Key Differences

  • Redux Toolkit focuses on simplifying Redux development with built-in utilities
  • Redux Immutable emphasizes using Immutable.js for state management
  • Redux Toolkit has more active development and community support
  • Redux Immutable is more lightweight but requires manual implementation of common Redux patterns

Use Cases

  • Choose Redux Toolkit for comprehensive Redux development with modern best practices
  • Opt for Redux Immutable when working with Immutable.js and needing a minimal Redux setup
8,477

The Redux Framework

Pros of Rematch

  • Simplified Redux setup with less boilerplate code
  • Built-in support for async actions and effects
  • Easier to scale and maintain large applications

Cons of Rematch

  • Learning curve for developers familiar with traditional Redux
  • Less flexibility in some advanced Redux scenarios
  • Potential performance overhead for very small applications

Code Comparison

Redux-immutable:

import { combineReducers } from 'redux-immutable';
import { fromJS } from 'immutable';

const initialState = fromJS({
  counter: 0
});

const rootReducer = combineReducers({
  counter: (state = initialState.get('counter'), action) => {
    switch (action.type) {
      case 'INCREMENT':
        return state + 1;
      default:
        return state;
    }
  }
});

Rematch:

import { init } from '@rematch/core';

const counter = {
  state: 0,
  reducers: {
    increment(state) {
      return state + 1;
    }
  }
};

const store = init({
  models: { counter }
});

Redux-immutable focuses on combining reducers with Immutable.js data structures, while Rematch provides a more concise and intuitive API for defining models and actions. Rematch simplifies the Redux setup process and reduces boilerplate, but may require adapting to a different mental model for state management.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

redux-immutable

GitSpo Mentions Travis build status NPM version Canonical Code Style

redux-immutable is used to create an equivalent function of Redux combineReducers that works with Immutable.js state.

When Redux createStore reducer is created using redux-immutable then initialState must be an instance of Immutable.Collection.

Problem

When createStore is invoked with initialState that is an instance of Immutable.Collection further invocation of reducer will produce an error:

The initialState argument passed to createStore has unexpected type of "Object". Expected argument to be an object with the following keys: "data"

This is because Redux combineReducers treats state object as a plain JavaScript object.

combineReducers created using redux-immutable uses Immutable.js API to iterate the state.

Usage

Create a store with initialState set to an instance of Immutable.Collection:

import {
  combineReducers
} from 'redux-immutable';

import {
  createStore
} from 'redux';

const initialState = Immutable.Map();
const rootReducer = combineReducers({});
const store = createStore(rootReducer, initialState);

By default, if state is undefined, rootReducer(state, action) is called with state = Immutable.Map(). A different default function can be provided as the second parameter to combineReducers(reducers, getDefaultState), for example:

const StateRecord = Immutable.Record({
	foo: 'bar'
});
const rootReducer = combineReducers({foo: fooReducer}, StateRecord);
// rootReducer now has signature of rootReducer(state = StateRecord(), action)
// state now must always have 'foo' property with 'bar' as its default value

When using Immutable.Record it is possible to delegate default values to child reducers:

const StateRecord = Immutable.Record({
	foo: undefined
});
const rootReducer = combineReducers({foo: fooReducer}, StateRecord);
// state now must always have 'foo' property with its default value returned from fooReducer(undefined, action)

In general, getDefaultState function must return an instance of Immutable.Record or Immutable.Collection that implements get, set and withMutations methods. Such collections are List, Map and OrderedMap.

Using with react-router-redux v4 and under

react-router-redux routeReducer does not work with Immutable.js. You need to use a custom reducer:

import Immutable from 'immutable';
import {
  LOCATION_CHANGE
} from 'react-router-redux';

const initialState = Immutable.fromJS({
  locationBeforeTransitions: null
});

export default (state = initialState, action) => {
  if (action.type === LOCATION_CHANGE) {
    return state.set('locationBeforeTransitions', action.payload);
  }

  return state;
};

Pass a selector to access the payload state and convert it to a JavaScript object via the selectLocationState option on syncHistoryWithStore:

import {
  browserHistory
} from 'react-router';
import {
  syncHistoryWithStore
} from 'react-router-redux';

const history = syncHistoryWithStore(browserHistory, store, {
  selectLocationState (state) {
      return state.get('routing').toJS();
  }
});

The 'routing' path depends on the rootReducer definition. This example assumes that routeReducer is made available under routing property of the rootReducer.

Using with react-router-redux v5

To make react-router-redux v5 work with Immutable.js you only need to use a custom reducer:

import {
  Map
} from 'immutable';
import {
  LOCATION_CHANGE
} from 'react-router-redux';

const initialState = Map({
  location: null,
  action: null
});

export function routerReducer(state = initialState, {type, payload = {}} = {}) {
  if (type === LOCATION_CHANGE) {
    const location = payload.location || payload;
    const action = payload.action;

    return state
      .set('location', location)
      .set('action', action);
  }

  return state;
}

NPM DownloadsLast 30 Days