Skip to content

✅ Best Practices for Mutating draftDb in Reflex #5

@flexsurfer

Description

@flexsurfer

Reflex uses Immer under the hood to detect changes in state via structural patches. These patches then drive the reactive system. To avoid unnecessary recomputations and reactions, it’s important to mutate draftDb in a way that minimizes the creation of redundant patches.


📌 How Immer Works (Key Detail)

Immer does not create a patch if:

if (origValue === value && op === REPLACE) return

That means:

  • If you assign the same value (by reference or primitive identity), no patch is created.
  • If you assign a new object, even with identical contents, a patch will be created.

✅ Safe Mutation Patterns (No Extra Reactions)

You do not need to manually check before assigning primitives:

produce(db, draft => {
  draft.user.name = 'John' // ✅ no patch if name was already 'John'
})

Immer will skip the patch if the value didn’t change.


⚠️ Unsafe Patterns That Trigger Unnecessary Patches

Avoid recreating objects/arrays unnecessarily:

produce(db, draft => {
  draft.user = { ...draft.user, name: 'John' } // ❌ always new reference
})

produce(db, draft => {
  draft.items = [...draft.items] // ❌ new array, even if unchanged
})

These produce patches, which trigger root reactions, even if logically nothing changed.


🛡️ Optional Manual Checks (When You’re Unsure)

In some cases, it’s safer to check manually — especially if there’s a chance of accidental object recreation:

produce(db, draft => {
  if (draft.user.name !== newName) {
    draft.user.name = newName
  }
})

This avoids unnecessary assignments and patch creation altogether.


🧠 Summary

Pattern Patch Created? Recommended
draft.value = samePrimitive ✅ Yes
draft.value = sameReference ✅ Yes
draft.value = {...value} (new object) ❌ Avoid unless needed
Manual check before assign ✅ Optional, for safety

🚀 Tip

Let Immer do the heavy lifting. You only need to be careful when working with objects, arrays, or references that might be unintentionally recreated. Avoiding these patterns helps Reflex skip unnecessary reaction updates.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions