Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Applying patches returns empty array after update to v1.11.0 #301

Closed
1 task done
hastebrot opened this issue Jan 23, 2019 · 4 comments · May be fixed by dyna-dot/create-react-app#4 or hzhz/create-react-app#3
Closed
1 task done

Comments

@hastebrot
Copy link

hastebrot commented Jan 23, 2019

  • Issue: Applying patches returns empty array after update to v1.11.0.

Works with immer v1.10.5. Does not work with immer v1.11.0 and v1.12.0.

Code to reproduce (in TypeScript):

import { produce, applyPatches } from "immer"

let patches = [] as any[]
const state0: { a: number, b?: number } = { a: 1 }
const state1 = produce(state0, (draft) => { draft.b = 9 }, (p) => { patches.push(...p) })
const state2 = produce(state1, (draft) => { draft.a = 3 }, (p) => { patches.push(...p) })
const state3 = produce(state2, (draft) => { draft.b = 99 }, (p) => { patches.push(...p) })
const state4 = produce(state3, (draft) => { draft.a = 5 }, (p) => { patches.push(...p) })

console.log(patches)
// [ { op: 'add', path: [ 'b' ], value: 9 },
//   { op: 'replace', path: [ 'a' ], value: 3 },
//   { op: 'replace', path: [ 'b' ], value: 99 },
//   { op: 'replace', path: [ 'a' ], value: 5 } ]

produce(state0, (draft) => { applyPatches(draft, patches) }, (p) => { patches = p })

console.log(patches)
// [ { op: 'add', path: [ 'b' ], value: 99 },
//   { op: 'replace', path: [ 'a' ], value: 5 } ]

console.log(state0)
// { a: 1 }
console.log(state4)
// { a: 5, b: 99 }

Code based on https://medium.com/@dedels/using-immer-to-compress-immer-patches-f382835b6c69.

Expected behavior: It logs the patches like in the comments.

Observed behavior: The second logged patches is an empty array [].

@hastebrot
Copy link
Author

Closing issue. I fixed it by returning the new draft after applying the patches.

Working example for immer v1.12.0 (in TypeScript):

import { produce, applyPatches } from "immer"

let patches = [] as any[]
const state0: { a: number, b?: number } = { a: 1 }
const state1 = produce(state0, (draft) => { draft.b = 9 }, (p) => { patches.push(...p) })
const state2 = produce(state1, (draft) => { draft.a = 3 }, (p) => { patches.push(...p) })
const state3 = produce(state2, (draft) => { draft.b = 99 }, (p) => { patches.push(...p) })
const state4 = produce(state3, (draft) => { draft.a = 5 }, (p) => { patches.push(...p) })

console.log(patches)
// [ { op: 'add', path: [ 'b' ], value: 9 },
//   { op: 'replace', path: [ 'a' ], value: 3 },
//   { op: 'replace', path: [ 'b' ], value: 99 },
//   { op: 'replace', path: [ 'a' ], value: 5 } ]

const state5 = produce(state0,
  (draft) => applyPatches(draft, patches),
  (p) => { patches = p }
)

console.log(patches)
// [ { op: 'replace', path: [], value: { a: 5, b: 99 } } ]

console.log(state0)
// { a: 1 }
console.log(state4)
// { a: 5, b: 99 }
console.log(state5)
// { a: 5, b: 99 }

@aleclarson
Copy link
Member

aleclarson commented Jan 23, 2019

This is an unintended breaking change. Thanks for reporting!

9a2e756 fixed a bug in #282, which is why v1.11.0+ is where this occurs. The applyPatches function is actually a curried producer, which is why it's affected by that PR.

I'm going to change applyPatches to mutate the draft like it did in v1.10.5 and under.

@aleclarson
Copy link
Member

In v1.12.1, the applyPatches function now mutates Immer drafts instead of producing a copy.
Note: It still creates a copy when a normal object is passed to it.

@aleclarson
Copy link
Member

🎉 This issue has been resolved in version 1.12.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment