A lightweight state management library that follows Flux/Redux architecture but uses React's latest `useContext` and `useReducer` hooks. It provides a simple and efficient way to manage global state in React applications.
npm install resurrectionA lightweight state management library that follows Flux/Redux architecture but uses React's latest useContext and useReducer hooks. It provides a simple and efficient way to manage global state in React applications.
- Type-safe context and state management
- Redux-like action creators and reducers
- React hooks for state access and dispatch
- Simple and complex context providers
- Automatic state initialization
- Redux-like connect HOC for components
``bash`
npm install resurrectionor
yarn add resurrection
First, define your state types and create a reducer using createSlice:
`typescript
import { createSlice, Draft, ContextStoreInitializer } from 'resurrection';
interface AppState {
users: User[];
settings: Settings;
}
interface User {
id: string;
email: string;
firstName: string;
lastName: string;
}
interface Settings {
theme: 'light' | 'dark';
language: string;
notifications: boolean;
}
// Define initial state
const initialState: AppState = {
users: [],
settings: {
theme: 'light',
language: 'en',
notifications: true,
},
};
// Create initializer function
export const getInitialState: ContextStoreInitializer
return {
...appInitialState,
...initialState,
};
};
// Define reducer actions
const SetUsers = (state: Draft
state.users = users;
};
const UpdateUser = (state: Draft
const index = state.users.findIndex((u) => u.id === user.id);
if (index !== -1) {
state.users[index] = user;
}
};
const UpdateSettings = (state: Draft
state.settings = {
...state.settings,
...settings,
};
};
// Create the reducer
export const appSlice = createSlice({
name: 'App',
initialState,
actions: {
SetUsers,
UpdateUser,
UpdateSettings,
},
});
`
Next, create your context and provider using the reducer:
`typescript
import { FC, Reducer } from 'react';
import {
createContextWithName,
Provider,
ReducerActionCreators,
} from 'resurrection';
import { getInitialState, initialState, appSlice } from './reducer';
import { AppState } from './types';
// Get action creators
export const appContextActions = appSlice.actions;
// Define actions type
type AppActions = ReducerActionCreators
// Create context
export const AppContext = createContextWithName
'App',
initialState
);
// Destructure context utilities
export const {
StateContext: AppStateContext,
useSelector: useAppSelector,
DispatchContext: AppDispatchContext,
useDispatch: useAppDispatch,
} = AppContext;
// Create provider component
export const AppContextProvider: FC<{
children: React.ReactNode;
initialState?: AppState;
}> = ({ children, ...restOfProps }) => {
return (
StateContext={AppStateContext}
reducer={appSlice.reducer as unknown as Reducer
initializer={getInitialState}
DispatchContext={AppDispatchContext}
>
{children}
);
};
`
Finally, wrap your application with the provider and use the context:
`typescript
// In your root layout or app component
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
// Fetch initial state (e.g., from API)
const initialState = await getInitialData();
return (
{children}
);
}
// In your components
const UserList = () => {
const users = useAppSelector((state) => state.users);
const dispatch = useAppDispatch();
return (
API Reference
$3
Creates a reducer with typed actions:
`typescript
createSlice({
name: string;
initialState: State;
actions: {
[key: string]: (state: Draft, payload: any) => void;
};
})
`$3
The
connect HOC provides a way to connect components to your context store, similar to Redux's connect pattern. Here's an example:`typescript
import { connect, ConnectHookProps, ConnectOptionUseEffectAfterChangeReturn } from 'resurrection';// Define your component props types
interface AppMapStateToProps {
items: Item[];
searchQuery: string;
}
interface AppMapDispatchToProps {
SetSearchQuery: (query: string) => void;
SetItems: (items: Item[]) => void;
}
interface AppOwnProps {
// Any additional props your component needs
}
type AppConnectedProps = AppMapStateToProps & AppMapDispatchToProps & AppOwnProps;
// Your component
const App: React.FC = ({
items,
searchQuery,
SetSearchQuery
}) => {
return (
value={searchQuery}
onChange={(e) => SetSearchQuery(e.target.value)}
/>
{/ Rest of your component /}
);
};
// Connect the component
export default connect<
AppMapStateToProps,
AppMapDispatchToProps,
AppOwnProps
>({
mapStateToPropsOptions: [
{
context: AppStateContext,
mapStateToProps: (state: AppState) => ({
items: state.items,
searchQuery: state.searchQuery
})
}
],
mapDispatchToPropsOptions: [
{
context: AppDispatchContext,
mapDispatchToProps: {
SetSearchQuery: appContextActions.SetSearchQuery,
SetItems: appContextActions.SetItems
}
}
],
useHookEffectAfterChange: ({
stateToProps,
dispatchToProps
}: ConnectHookProps<
AppMapStateToProps,
AppMapDispatchToProps,
AppOwnProps
>): ConnectOptionUseEffectAfterChangeReturn => {
const value = stateToProps.searchQuery as T;
const callback = dispatchToProps.SetItems;
const condition = (prevValue: T, value: T) => prevValue !== value;
return [value, callback, condition];
}
})(App);
`The
connect HOC accepts three type parameters:1.
TMapStateToProps: The type of props that will be mapped from state
2. TMapDispatchToProps: The type of props that will be mapped from dispatch
3. TOwnProps: The type of props that the component accepts directlyThe configuration object accepts:
-
mapStateToPropsOptions: Array of state mapping configurations
- mapDispatchToPropsOptions: Array of dispatch mapping configurations
- useHookEffectAfterChange: Optional effect hook for handling state changes$3
The context provides several utilities:
-
StateContext: The context for accessing state
- DispatchContext: The context for dispatching actions
- useSelector: Hook for selecting state
- useDispatch: Hook for dispatching actions$3
`typescript
interface ProviderProps {
StateContext: React.Context;
DispatchContext: React.Context>;
reducer: Reducer;
initializer: ContextStoreInitializer;
initialState?: T;
children: React.ReactNode;
}
`Development
This library was generated with Nx.
$3
Run
nx test resurrection` to execute the unit tests via Vitest.MIT © nathanhfoster