redux-toolkit-state
Version:
🚀 A powerful & lightweight React hook library that simplifies Redux state management with a familiar useState-like API. Built on Redux Toolkit for optimal performance.
86 lines (85 loc) • 3.41 kB
JavaScript
import { useCallback, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createSliceForKey, getSliceForKey } from '../store';
/**
* Custom hook for redux State management
* @param key - Unique identifier for the redux State
* @param initialValue - Initial value for the state
* @returns [value, setValue, { update, reset }]
*/
export const useReduxStateWithInitial = (key, initialValue) => {
const dispatch = useDispatch();
// Create or get the slice for this key
const slice = useMemo(() => {
const existingSlice = getSliceForKey(key);
if (existingSlice)
return existingSlice;
return createSliceForKey(key, initialValue);
}, [key, initialValue]);
/** (getter Function)
* This uses the useSelector hook to access the Redux store and retrieve the value associated with the given key.
*
* @param state - The Redux state
* @returns The value associated with the key
*/
const value = useSelector((state) => state[key]);
// Setter function (similar to useState)
const setValue = useCallback((newValue) => {
if (typeof newValue === 'function') {
const updater = newValue;
dispatch(slice.actions.setValue(updater(value)));
}
else {
dispatch(slice.actions.setValue(newValue));
}
}, [dispatch, slice.actions, value]);
// Update function for partial updates (useful for objects)
const update = useCallback((updates) => {
dispatch(slice.actions.updateValue(updates));
}, [dispatch, slice.actions]);
// Reset function to restore initial value
const reset = useCallback(() => {
dispatch(slice.actions.reset(undefined));
}, [dispatch, slice.actions]);
// Initialize the state if it doesn't exist
useEffect(() => {
if (value === undefined) {
setValue(initialValue);
}
}, [value, initialValue, setValue]);
// Return the value or initial value if undefined
const currentValue = value !== undefined ? value : initialValue;
return [currentValue, setValue, { update, reset }];
};
/**
* Custom hook for accessing existing redux State
* @param key - Unique identifier for the redux State
* @returns [value, setValue, { update, reset }]
*/
export const useReduxStateExisting = (key) => {
const dispatch = useDispatch();
// Try to get existing slice
const existingSlice = getSliceForKey(key);
if (!existingSlice) {
throw new Error(`redux State with key "${key}" does not exist. Please provide an initial value.`);
}
const value = useSelector((state) => {
return state[key];
});
const setValue = useCallback((newValue) => {
if (typeof newValue === 'function') {
const updater = newValue;
dispatch(existingSlice.actions.setValue(updater(value)));
}
else {
dispatch(existingSlice.actions.setValue(newValue));
}
}, [dispatch, existingSlice.actions, value]);
const update = useCallback((updates) => {
dispatch(existingSlice.actions.updateValue(updates));
}, [dispatch, existingSlice.actions]);
const reset = useCallback(() => {
dispatch(existingSlice.actions.reset(undefined));
}, [dispatch, existingSlice.actions]);
return [value, setValue, { update, reset }];
};