22

I am learning ngxs but I can't understand when should I use patchState and setState? What's the difference?

const state = ctx.getState();
let data =  this.service.list();
ctx.setState({
    ...state,
    feedAnimals: data
});

vs.

let data =  this.service.list();
ctx.patchState({
    feedAnimals: data
});
Machado
  • 8,965
  • 6
  • 43
  • 46

2 Answers2

23

Those two pieces of code are equivalent. patchState is just a short hand version of the setState({...state, ... } code.

In future patchState will most likely be evolving to a more useful immutability helper with equality testing (ie. the state would only be changed if the patch actually changes any values) and patch operators (this is still in discussion).

I would recommend using patchState for neatness and to take advantage of features that are on their way.

Mark Whitfeld
  • 6,500
  • 4
  • 36
  • 32
  • 1
    Thank you for your unswer! But in source code [link] (https://github.com/ngxs/store/blob/46a4cc557dfb7baed93675f4c9c445ca3fc87f47/packages/store/src/state-factory.ts) patchState make clone the object. What about perfomance? – Александр Шатилов May 22 '18 at 08:37
  • 1
    Read up about the benefits of immutability with regard to performance. Making a clone of an object is not expensive compared to traversing a mutated object in every change detection cycle to check for changes. Look up Performance Tuning Angular on YouTube there are many great videos there (I'd recommend the ones by Minko Gechev) – Mark Whitfeld May 26 '18 at 16:25
20

IT DOESN'T WORK PROPERLY

const state = context.getState();
state.permissions = action.payload;
context.setState(state);

IT WORKS

const state = context.getState();
state.permissions = action.payload;
context.setState({ ...state });

IT WORKS

const state = context.getState();
state.permissions = action.payload;
context.patchState(state);

All the examples update the state... but the first one doesn't activate the observable for state changes, because state is immutable, that means you cannot simple edit it and save it, it is not editable and you always will have to clone the old state, edit your new copy and save this new state. patchState just does it for you.

Machado
  • 8,965
  • 6
  • 43
  • 46
Michalis
  • 6,686
  • 13
  • 52
  • 78
  • Gosh! I have been struggling with the first one for like an hour. Wish I could give you 10 upvotes for pointing that out. Is it a bug or is it how its supposed to work? – dasfdsa Jul 14 '18 at 05:53
  • 1
    For some reason this doesn't work: `context.setState({...state, someProp: action.payload})`. Can you explain why? That's how it is on the docs – António Quadrado Nov 21 '18 at 11:31
  • {...state, ...{someProp: action.payload}} Try this – Michalis Nov 21 '18 at 13:01
  • 1
    @dasfdsa Yes, that's how it is supposed to work. NGXS detects changes to the identity of the state object. Identity changes when the object assigned to `state` changes. So if I do `state.property = 'some new value;` then even though `state` has been modified, it's still the same variable. If I do `state = {}` and pass that to `setState()`, then it will register as a change. – daktaklakpak May 22 '19 at 14:07