Compare React State Objects Online

Paste two React state snapshots. See what changed between renders — field by field.

🔒 100% private — runs entirely in your browser

or try sample data

What is React State Diff?

React State Diff compares two React component state objects and shows you exactly which fields were added, removed, or modified between renders. Whether you are debugging unexpected re-renders, tracking down state mutation bugs, or verifying that a reducer produces the correct output, this tool gives you a clear, color-coded view of every change in your state tree.

React components re-render when their state changes, but understanding what changed and why is often the hard part. Logging state with console.log produces walls of text that are difficult to scan. React DevTools shows current state but does not highlight what just changed. This tool fills that gap — paste the before and after state, and instantly see the precise differences at every nesting level.

Works with any JSON-serializable state — useState objects, Redux store slices, Zustand stores, React Query cache entries, or context values. Copy state from React DevTools, Redux DevTools, or your own logging. The comparison runs entirely in your browser so your application data stays private.

React State Comparison — Common Scenarios

Debugging a cart update action

// Before dispatch: addToCart("SKU-112")
{ "cart": { "items": [ { "productId": "SKU-001", "quantity": 1 } ], "subtotal": 79.99 }
} // After dispatch: expected quantity bump + new item
{ "cart": { "items": [ { "productId": "SKU-001", "quantity": 1 }, { "productId": "SKU-112", "quantity": 1 } ], "subtotal": 104.98 }
} // Paste both snapshots to verify:
// - New item was added correctly
// - Subtotal was recalculated
// - No other fields were mutated

After dispatching an action, compare the state before and after to confirm only the intended fields changed. Unexpected changes indicate a mutation bug or overly broad reducer logic.

Tracking re-render causes with useEffect dependencies

// Log state in useEffect to capture snapshots:
useEffect(() => { console.log('State snapshot:', JSON.stringify(state, null, 2));
}); // Copy the logged JSON from two consecutive renders
// and paste them into the diff panels. // Common findings:
// - A nested object changed reference but not value
// - An array was re-created on every render
// - A derived value recalculated unnecessarily

Unnecessary re-renders often come from creating new object or array references on every render. The diff tool shows when values are identical but references changed, helping you identify where to add useMemo or useCallback.

Comparing Redux store slices

// Redux DevTools > State > Raw tab
// Copy the store state before and after an action // Before: user/fetchProfile/fulfilled
{ "auth": { "token": "abc", "isAuthenticated": true }, "profile": { "name": "Alice", "role": "viewer" }, "notifications": { "unread": 3, "items": [...] }
} // After: user/updateRole
{ "auth": { "token": "abc", "isAuthenticated": true }, "profile": { "name": "Alice", "role": "admin" }, "notifications": { "unread": 3, "items": [...] }
} // Diff confirms only profile.role changed

Redux DevTools has a built-in diff view, but pasting into this tool lets you compare states across different sessions or share the diff with teammates.

React State Comparison Gotchas

Non-serializable state values

React state can contain functions, Dates, Maps, Sets, and class instances that are not JSON-serializable. When you copy state from DevTools or JSON.stringify(), these values are lost — functions become undefined, Dates become strings, and Maps become empty objects. Compare only the serializable portion of your state.

Reference equality vs value equality

React re-renders when state references change, even if the values are identical. This tool compares by value, not reference. Two objects that look identical in the diff may still cause re-renders if they are different references in memory. Use Object.is() or React DevTools Profiler to check reference equality.

Circular references in state

If your state contains circular references (e.g., parent-child relationships where children reference their parent), JSON.stringify() will throw an error. Use a replacer function like JSON.stringify(state, getCircularReplacer()) to handle these before pasting into the diff tool.

Frequently Asked Questions

How do I compare React state between renders?

Copy the state object from React DevTools before and after the render, paste both snapshots into the two panels, and click Compare. The tool highlights every field that was added, removed, or modified between the two state snapshots.

Can I compare Redux or Zustand store state?

Yes. Any JSON-serializable state object works, including Redux store snapshots from Redux DevTools, Zustand state, Jotai atom values, Recoil selectors, and MobX observable snapshots exported with toJS().

How do I detect accidental state mutations?

Paste the state before and after a suspected mutation. If fields changed that your action or event handler did not intend to update, you have found a mutation bug. Common culprits include directly modifying nested objects or arrays instead of creating new copies with the spread operator.

Is my application state data safe?

Yes. This tool runs entirely in your browser using client-side JavaScript. Your component state, user data, and application logic are never sent to any server.

Can I compare state from React DevTools directly?

Yes. In React DevTools, select a component in the Components tab, right-click any state or props value, and choose "Copy value to clipboard." Paste it into one panel, trigger the state change, copy the updated state, and paste it into the other panel.

How do I handle large state trees?

For large state trees, consider comparing only the relevant slice rather than the entire store. Copy just the sub-tree you are interested in (e.g., state.cart instead of the full state). This reduces noise and makes the diff output easier to read.