I would be wary of editing config files in some cases since the structure seems to change over a short period of time so basic functionality does not work as some low level dependencies change. For example, HMR does work with some versions of myriad NPM packages but not others. Updating components such as the Aurelia router can have similar results. Sometimes very little change to a configuration file can break a working system. Webpack seems to be a common factor so perhaps it is not doing what we think it should.
I was curious on how they differ so i created the todo app in both and wrote up some observations
if there is anything you think i missed let me know, i will see if i can update the observations.
For every person that sees a single file as an advantage there will be someone that sees it as a negative. I donāt want my html mixed with code personally.
Both Vue and Aurelia call themselves frameworks so this is pretty weird argument.
Vue has reactive binding too, and it applies to the official state management too. Iām wondering why Aurelia decided to go with immutable state management, since there seems to go most of the reactivity. If you use aurelia store, it seems like every time you update anything in your state, every single component subscribing to state will be re-rendered. At this point, reactive binding is no help and not using virtual DOM is a downside as youāll quickly run into performance problems if you donāt work around them. At this point you also have wrote more code to bind to the state than you would in Vue. Iām not that experienced with Aurelia, so maybe thereās some trivial way to work around this, but itās not covered in the documentation.
I do know about pluck and distinctUntilChanged, but thatās a lot manual work which isnāt needed at all with Vuex.
Your thought about re-rendering everything was my thought too. Can someone say if this is not the case. Iāve found using the store is more trouble than it is worth in my application. I still have it in place, but Iām kind of using it as a local repository and I feed a data adapter with it now.
We were accidentally doing deep clone of the whole state every change, so I can confirm that we were doing something wrong
The principle that Aurelia and probably any other lib/framework follow when employing reactive binding: only re-render when new value is not the same with existing value.
For Aurelia store, consider following examples:
<span>${store.state.userName}</span>
<span>${store.state.address.main}</span>
<span>${userName}</span>
@selector({`
userName: store => store.state.userName
})
export class MyEl {}
With initial store state:
{
userName: '',
address: {
main: ''
}
}
Scenario 1: Store state is then changed, with something like this:
store.state = {
userName: 'new-user-name',
address: oldState.address
}
In this case, state
object of the store has been changed, so binding will re-check their values. After evaluation:
-
<span>${store.state.userName}</span>
needs to rerender because value''
atstate.userName
has been changed to'new-user-name'
-
<span>${userName}</span>
of (2) needs to rerender for the same reason. -
<span>${store.state.address.main}</span>
does not rerender because value''
atstate.address.main
has not been changed
Scenario 2: Store state is then changed, with something like this:
store.state = {
userName: 'new-user-name',
address: { ...address }
}
-
<span>${store.state.userName}</span>
needs to rerender because value''
atstate.userName
has been changed to'new-user-name'
-
<span>${userName}</span>
of (2) needs to rerender for the same reason. -
<span>${store.state.address.main}</span>
does not rerender because value''
atstate.address.main
has not been changed
Bindings re-check values when view model value/property changes at some path. But they do not re-render unnecessarily.
So if you see it rerenders, then itās definitely a bug. But I do not see those in my app, so if you are experiencing perf issue, maybe put together some repro and we can try to work it out what went wrong.
What kind of troubles is it causing for you?
Ultimately I donāt believe it belongs in every application. My application cannot rely on one state, i need to have multiple states for different components (pages). Maybe documentation still isnāt clear enough to me, but it was adding complexity to places it isnāt needed. My overall state model can be changing by external events (signalr), which affects one portion of the state and the user may do an update on something which also affects the state. I want to be history aware and because my state can constantly change, iām not sure how to do that. External changes cannot be undone for instance.
There was a good article about when to use state management and not to, but i cantā locate it. That article basically talked me out of fighting this battle with the store plugin. Iām not in anyway saying the store plugin is bad, I just feel better having my own rolled āstoreā
Not directly related to the topic, but a question on your example:
The address spread operator here is just cloning the address properties (in this case āmainā) which is just a shortcut to what was used in the first example right? I am assuming its creating a new array, and was just showing that values are checked, not just references?
I think you are on the right track. A single state store is just a design pattern collection which works great for a lot use cases but certainly not everyone. All your concerns mentioned are certainly doable with the plugin by properly structuring the state, using middlewares or Event subscriptions to handle external inputs like SignalR, or even create multiple Store instances and sync them via middlewares (remember its just a class). But then again a few classic services used together with event aggregation and a custom roled undo behavior can certainly be enough.
Personally I feel the right moment for single Store state management is when you get the feeling that to many event sources start to manipulate data and you keep adding all services to every component and debugging the flow or tracking down the root cause becomes very hard.
As an example, Iām building a whole IDE where pretty much every Panel, setting or command can affect every part of the app. So this falls into above description and for me feels like a perfect candidate.
So to conclude, dont feel bad because not every tool fits your needs. Perhaps a simple screw driver is all you need and not a fully loaded workbench
It spreads the object, in that example, itās quite similar to:
address = Object.assign({}, oldState.address)
In first example, it uses the old adress
object object while it creates a new object in the 2nd one. Spread can be used with either object or array.
Ok, I think we are saying the same thing, just using different terminology. I looked it up on the Mozilla site before asking, just wanted to be sure I was understanding how it was being used clearly, and using spread does create a new reference object just as the Object.assign example does.
If you have a property on your oldState that is an array of objects, The array objects are still references to the original at this point arenāt they? I donāt use object assign for extremely complex objects in any of my current code and Iām not in a spot i can do my own quick research test.
Yes, it should still be the original array. Unless you create new array based on elements of old array via spread, slice etc.
Thanks, I think that is an important gotcha to know about. Often I just convert my object to a string and back to an object, Iām not sure how bad performance is, but when Iām doing it I generally donāt care. At least at this point i know my object is a real copy with no references to the original
Perf wise not the best but definitely a reliable way to deepclone plus it strips off all methods.
Is that second scenario description correct? It looks like the first scenarios description was just copy/pasted to the second scenario?
The first scenario is about replacing a property of an object, the 2nd is about replacing the entire state object. Does this help? If not, please suggest changes Iāll try to make it clearer