Skip to main content

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.

  1. Add @genesislcap/foundation-redux as a dependency in your package.json file. Whenever you change the dependencies of your project, ensure you run the $ npm run bootstrap command 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], {});

Subscribe to the store from your UI:

import { useEffect, useState } from 'react';

export function UserComponent() {
const [userName, setUserName] = useState('');

useEffect(() => {
return store.subscribeKey(
(state) => state.user.name,
(state) => setUserName(state.user.name),
);
}, []);

const handleLogin = () => {
actions.user.setUser({ name: 'John Doe', email: 'john@example.com' });
};

return <div>Hello {userName}!</div>;
}

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:

  1. Replace store creation: Use createStore instead of store fragments
  2. Convert event handlers: Replace custom events with Redux actions
  3. Update subscriptions: Use subscribeKey instead of binding observers
  4. Simplify state updates: Let Redux Toolkit handle immutability

API​

You can find out more details in our API docs.