Genesis Foundation Redux
foundation-redux provides Redux Toolkit integration for Genesis components, offering a clean and efficient way to manage application state using the proven Redux pattern.
Background
This package was created to provide an alternative to foundation-store by leveraging the power and ecosystem of Redux Toolkit. While foundation-store implements a Redux-like pattern within the Genesis context, foundation-redux provides direct bindings to Redux itself, allowing developers to benefit from:
- Vast Redux documentation and ecosystem
- Redux DevTools integration
- Proven patterns and best practices
- Extensive community support
- Built-in immutability handling
Why Choose foundation-redux over foundation-store?
Reduced Boilerplate
Foundation store requires manual immutability handling and custom event setup, while Redux Toolkit handles immutability automatically.
Foundation store example:
this.createListener<DeleteViewDerivedFieldPayload>(
  StoreEvents.DeleteViewDerivedField,
  ({ view, field }) => {
    const { [field]: fieldToDelete, ...rest } =
      this.commit.genesisCreateConfig.views.views[view]?.derivedFields || {};
    if (fieldToDelete) {
      this.commit.genesisCreateConfig = {
        ...this.genesisCreateConfig,
        views: {
          views: {
            ...this.genesisCreateConfig.views.views,
            [view]: {
              ...this.genesisCreateConfig.views.views[view],
              derivedFields: {
                ...rest,
              },
            },
          },
        },
      };
    }
  },
);
Redux Toolkit example:
deleteDerivedField(state, { payload: { view, field } }) {
  delete state[view].derivedFields[field];
}
Ecosystem Benefits
- Redux DevTools: Built-in debugging and time-travel debugging
- Middleware: Extensive middleware ecosystem
- Entity Adapters: Auto-generated CRUD actions and selectors
- Serialization: Built-in support for local storage and hydration
Installation
To enable this module in your application, follow the steps below.
- Add @genesislcap/foundation-reduxas a dependency in yourpackage.jsonfile. Whenever you change the dependencies of your project, ensure you run the$ npm run bootstrapcommand again.
{
  ...
  "dependencies": {
    ...
    "@genesislcap/foundation-redux": "latest"
    ...
  },
  ...
}
Usage
Basic Store Setup
import { createStore } from '@genesislcap/foundation-redux';
import { createSlice } from '@reduxjs/toolkit';
import { customElement, GenesisElement, observable } from '@genesislcap/web-core';
// Define your slices
const userSlice = createSlice({
  name: 'user',
  initialState: { name: '', email: '' },
  reducers: {
    setUser: (state, action) => {
      state.name = action.payload.name;
      state.email = action.payload.email;
    },
    clearUser: (state) => {
      state.name = '';
      state.email = '';
    },
  },
  selectors: {
    getUserName: (state) => state.name,
    getUserEmail: (state) => state.email,
  },
});
// Create the store
const { store, actions, selectors } = createStore([userSlice], {});
@customElement({
  name: 'user-component',
  template: html`<div>Hello ${(x) => x.userName}!</div>`,
})
export class UserComponent extends GenesisElement {
  @observable userName = '';
  connectedCallback() {
    super.connectedCallback();
    
    // Subscribe to store changes
    store.subscribeKey(
      (state) => state.user.name,
      (state) => {
        this.userName = state.user.name;
      }
    );
  }
  handleLogin() {
    actions.user.setUser({ name: 'John Doe', email: 'john@example.com' });
  }
}
Advanced Features
- Thunk Actions: Support for async operations
- Entity Adapters: Auto-generated CRUD operations
- DevTools: Full Redux DevTools integration
- Middleware: Custom middleware support
- Local Storage: Built-in persistence helpers
API Reference
createStore(slices, preloadedState)
Creates a Redux store with Genesis component integration.
Parameters:
- slices: Array of Redux Toolkit slices
- preloadedState: Initial state for the store
Returns:
- store: Proxied state object for reactive updates
- actions: Bound action creators
- selectors: Bound selectors
- dispatch: Redux dispatch function
- subscribe: Store subscription function
- subscribeKey: Key-based subscription for performance
- notify: Manual notification trigger
Store Integration
The store automatically integrates with Genesis's Observable system, providing reactive updates when state changes. Components can subscribe to specific state changes using subscribeKey for optimal performance.
Migration from foundation-store
If you're currently using foundation-store, migration to foundation-redux involves:
- Replace store creation: Use createStoreinstead of store fragments
- Convert event handlers: Replace custom events with Redux actions
- Update subscriptions: Use subscribeKeyinstead of binding observers
- Simplify state updates: Let Redux Toolkit handle immutability
API
You can find out more details in our API docs.