From harness-claude
Guides state selection patterns for Zustand, Redux, Jotai, and React Context to minimize component re-renders from over-subscription or unstable references.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Select and derive state efficiently to minimize component re-renders across any state management library
Optimizes Zustand re-renders in React using selectors, useShallow, shallow comparisons, and transient subscriptions. Use for excessive re-renders, multiple field selection, or non-render updates like animations.
Applies Zustand best practices for React apps including store architecture, selector optimization, re-render prevention, and SSR integration. Use when creating, reviewing, or refactoring stores.
Guides selection and correct implementation of frontend state management patterns using Redux, Zustand, MobX, Jotai, Recoil, and React Context. Addresses global state, prop drilling, and store architecture.
Share bugs, ideas, or general feedback.
Select and derive state efficiently to minimize component re-renders across any state management library
// Pattern 1: Zustand — inline selector
const userName = useStore((s) => s.user.name);
// Only re-renders when user.name changes (reference equality)
// Pattern 2: Zustand — multiple fields with useShallow
import { useShallow } from 'zustand/react/shallow';
const { name, email } = useStore(useShallow((s) => ({ name: s.user.name, email: s.user.email })));
// Pattern 3: Redux — createSelector for derived data
import { createSelector } from '@reduxjs/toolkit';
const selectTodos = (state: RootState) => state.todos.items;
const selectFilter = (state: RootState) => state.todos.filter;
const selectVisibleTodos = createSelector(
[selectTodos, selectFilter],
(todos, filter) => {
if (filter === 'all') return todos;
return todos.filter((t) => (filter === 'completed' ? t.completed : !t.completed));
}
);
// Pattern 4: Jotai — derived atoms
const visibleTodosAtom = atom((get) => {
const todos = get(todosAtom);
const filter = get(filterAtom);
return filter === 'all' ? todos : todos.filter((t) => t.completed === (filter === 'completed'));
});
// Pattern 5: useMemo for component-level derivations
function FilteredList({ filter }: { filter: string }) {
const items = useStore((s) => s.items);
const filtered = useMemo(
() => items.filter((i) => i.category === filter),
[items, filter]
);
return <List items={filtered} />;
}
Why reference equality matters: React and state libraries use Object.is (reference equality) to decide if a component should re-render. If your selector returns todos.filter(...), it creates a new array on every call, even if the contents are identical. The component re-renders every time.
Memoization strategies by library:
| Library | Strategy | Tool |
|---|---|---|
| Redux | Input memoization | createSelector (Reselect) |
| Zustand | Shallow equality | useShallow |
| Jotai | Atom dependency graph | Derived atoms |
| React | Component-level memo | useMemo |
Selector composition pattern:
// Base selectors (simple accessors)
const selectUsers = (state: RootState) => state.users.items;
const selectCurrentUserId = (state: RootState) => state.auth.userId;
// Composed selector (derived from base selectors)
const selectCurrentUser = createSelector([selectUsers, selectCurrentUserId], (users, userId) =>
users.find((u) => u.id === userId)
);
// Further composition
const selectCurrentUserPosts = createSelector([selectCurrentUser, selectPosts], (user, posts) =>
user ? posts.filter((p) => p.authorId === user.id) : []
);
When NOT to memoize: Primitive values (numbers, strings, booleans) are compared by value. useStore((s) => s.count) never creates a new reference — no memoization needed. Only memoize when the selector returns objects, arrays, or computes derived data.
Performance debugging: Use React DevTools Profiler to identify components that re-render unnecessarily. Check what selector results change between renders. Use why-did-you-render for automated detection.
https://react.dev/reference/react/useMemo