CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-redux

Official React bindings for Redux state management with hooks and higher-order components

Pending
Overview
Eval results
Files

hooks.mddocs/

React Redux Hooks

Modern React hooks for accessing Redux store state and dispatch functions with optimal performance and type safety.

Capabilities

useSelector Hook

Extracts data from Redux store state with automatic re-rendering when selected data changes. Uses shallow equality by default but supports custom equality functions.

/**
 * Hook for extracting data from Redux store state
 * @param selector - Function that receives state and returns selected data
 * @param equalityFnOrOptions - Optional equality function or options object
 * @returns Selected data from store state
 */
interface UseSelector<StateType = unknown> {
  <TState extends StateType = StateType, Selected = unknown>(
    selector: (state: TState) => Selected,
    equalityFnOrOptions?: EqualityFn<Selected> | UseSelectorOptions<Selected>
  ): Selected;
  
  withTypes: <OverrideStateType extends StateType>() => UseSelector<OverrideStateType>;
}

const useSelector: UseSelector;

interface UseSelectorOptions<Selected = unknown> {
  equalityFn?: EqualityFn<Selected>;
  devModeChecks?: Partial<DevModeChecks>;
}

type EqualityFn<T> = (a: T, b: T) => boolean;

Usage Examples:

import { useSelector } from "react-redux";

// Basic usage
const todos = useSelector((state: RootState) => state.todos);

// With custom equality function
const todoCount = useSelector(
  (state: RootState) => state.todos.length,
  (prev, next) => prev === next
);

// With options object
const visibleTodos = useSelector(
  (state: RootState) => state.todos.filter(todo => todo.visible),
  {
    equalityFn: (prev, next) => prev.length === next.length,
    devModeChecks: { stabilityCheck: 'once' }
  }
);

// Using pre-typed hook
const useAppSelector = useSelector.withTypes<RootState>();
const user = useAppSelector((state) => state.user); // Fully typed

useDispatch Hook

Returns the dispatch function from the Redux store, allowing components to dispatch actions.

/**
 * Hook for accessing Redux store dispatch function
 * @returns Dispatch function from the store
 */
interface UseDispatch<DispatchType extends Dispatch<UnknownAction> = Dispatch<UnknownAction>> {
  <AppDispatch extends DispatchType = DispatchType>(): AppDispatch;
  withTypes: <OverrideDispatchType extends DispatchType>() => UseDispatch<OverrideDispatchType>;
}

const useDispatch: UseDispatch;

Usage Examples:

import { useDispatch } from "react-redux";

// Basic usage
const dispatch = useDispatch();

const handleAddTodo = (text: string) => {
  dispatch({ type: "ADD_TODO", payload: text });
};

// With thunk actions
const handleAsyncAction = async () => {
  dispatch(fetchUserData(userId));
};

// Using pre-typed hook
const useAppDispatch = useDispatch.withTypes<AppDispatch>();
const dispatch = useAppDispatch(); // Typed with thunk support

useStore Hook

Returns the Redux store instance directly. Rarely needed as useSelector and useDispatch cover most use cases.

/**
 * Hook for accessing Redux store instance
 * @returns The Redux store instance
 */
interface UseStore<StoreType extends Store> {
  (): StoreType;
  <StateType extends ReturnType<StoreType['getState']> = ReturnType<StoreType['getState']>, 
   ActionType extends Action = ExtractStoreActionType<Store>>(): Store<StateType, ActionType>;
  withTypes: <OverrideStoreType extends StoreType>() => UseStore<OverrideStoreType>;
}

const useStore: UseStore<Store>;

type ExtractStoreActionType<StoreType extends Store> = 
  StoreType extends Store<any, infer ActionType> ? ActionType : never;

Usage Examples:

import { useStore } from "react-redux";

// Basic usage
const store = useStore();

// Access current state directly
const currentState = store.getState();

// Subscribe to store changes (not recommended, use useSelector instead)
useEffect(() => {
  const unsubscribe = store.subscribe(() => {
    console.log("Store updated:", store.getState());
  });
  return unsubscribe;
}, [store]);

// Using pre-typed hook
const useAppStore = useStore.withTypes<AppStore>();
const store = useAppStore(); // Fully typed store

Hook Factory Functions

Create custom hooks that use a different React context, useful for multiple store scenarios.

/**
 * Creates a custom useSelector hook for a specific context
 * @param context - React context to use instead of default ReactReduxContext
 * @returns Custom useSelector hook bound to the context
 */
function createSelectorHook<StateType = unknown>(
  context?: Context<ReactReduxContextValue<StateType> | null>
): UseSelector<StateType>;

/**
 * Creates a custom useDispatch hook for a specific context
 * @param context - React context to use instead of default ReactReduxContext
 * @returns Custom useDispatch hook bound to the context
 */
function createDispatchHook<StateType = unknown, ActionType extends Action = UnknownAction>(
  context?: Context<ReactReduxContextValue<StateType, ActionType> | null>
): UseDispatch<Dispatch<ActionType>>;

/**
 * Creates a custom useStore hook for a specific context
 * @param context - React context to use instead of default ReactReduxContext
 * @returns Custom useStore hook bound to the context
 */
function createStoreHook<StateType = unknown, ActionType extends Action = Action>(
  context?: Context<ReactReduxContextValue<StateType, ActionType> | null>
): UseStore<Store<StateType, ActionType>>;

Usage Examples:

import { createContext } from "react";
import { createSelectorHook, createDispatchHook, createStoreHook } from "react-redux";

// Create custom context for second store
const SecondaryContext = createContext(null);

// Create custom hooks
const useSecondarySelector = createSelectorHook(SecondaryContext);
const useSecondaryDispatch = createDispatchHook(SecondaryContext);
const useSecondaryStore = createStoreHook(SecondaryContext);

// Use in components
function ComponentWithSecondaryStore() {
  const data = useSecondarySelector((state) => state.data);
  const dispatch = useSecondaryDispatch();
  const store = useSecondaryStore();
  
  return <div>{data}</div>;
}

// Create pre-typed custom hooks with withTypes()
const useSecondaryAppSelector = useSecondarySelector.withTypes<SecondaryRootState>();
const useSecondaryAppDispatch = useSecondaryDispatch.withTypes<SecondaryAppDispatch>();

Development Features

Development Mode Checks

React Redux includes built-in development checks to help identify common issues:

type DevModeCheckFrequency = 'never' | 'once' | 'always';

interface DevModeChecks {
  stabilityCheck: DevModeCheckFrequency;
  identityFunctionCheck: DevModeCheckFrequency;
}
  • Stability Check: Warns when selectors return different results for the same input
  • Identity Function Check: Warns when selectors return the entire state object
  • Frequency Options:
    • 'never': Disable the check
    • 'once': Run check only once per selector
    • 'always': Run check on every selector call

Configuration:

// Configure checks in Provider
<Provider 
  store={store}
  stabilityCheck="once"
  identityFunctionCheck="always"
>
  <App />
</Provider>

// Configure checks per selector
const data = useSelector(
  (state) => state.data,
  { devModeChecks: { stabilityCheck: 'never' } }
);

Pre-typed Hooks (.withTypes() Methods)

React Redux 9.1.0+ supports pre-typed hooks for better TypeScript developer experience:

// Define your app types
type RootState = ReturnType<typeof store.getState>;
type AppDispatch = typeof store.dispatch;
type AppStore = typeof store;

// Create pre-typed hooks
export const useAppSelector = useSelector.withTypes<RootState>();
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppStore = useStore.withTypes<AppStore>();

// Use throughout your app with full type safety
const todos = useAppSelector((state) => state.todos); // state is typed as RootState
const dispatch = useAppDispatch(); // dispatch is typed as AppDispatch

Install with Tessl CLI

npx tessl i tessl/npm-react-redux

docs

connect.md

hooks.md

index.md

typescript.md

tile.json