Closed bep closed 8 years ago
Hi @bep
From my experience, the most you try to make you render updates more selective (like only re-render when user.profile
has changed) the hardest is to keep the control of your application.
Freezer paradigm is based on re-render everything when something changes, it may sound inefficient, but believe me, I have never had performance issues with this approach even with applications that mutates the data so frequently as a svg editor (dragging and dropping multiple elements with real-time ui feedback).
If you need to detect changes inside some node, you can still create a listener in it, and subscribe to its changes:
var store = new Freezer({user:{profile:{}, orders:[]}});
var listener = store.get().user.profile.getListener();
listener.on('update' () => console.log( "The profile changed" ) );
I only would use this approach in case that I have to update something outside the react world, and I don't get the props populated automatically by the main re-render call.
But, the main reason of freezer not offering info of what has changed is that you can have the same data repeated in multiple places of the state. For example:
var store = new Freezer({
users: [{id: 1, name: 'John'}, {id: 2, name: 'Alice'}],
currentUser: false
});
var state = store.get();
state.set({currenUser: state.users[0]});
// Now john is repeated inside the state
// This will change state.currentUser.name and state.users[0].name
store.get().currentUser.set({name: 'Bill'});
console.log( store.get() );
/*
{
users: [{id: 1, name: 'Bill'}, {id: 2, name: 'Alice'}],
currentUser: {id: 1, name: 'Bill'}
}
*/
One update can change multiple parts of the store, so it's really hard and expensive to check what's changed.
var listener = store.get().user.profile.getListener(); listener.on('update' () => console.log( "The profile changed" ) );
Hmm... Pretty sure I tested this ... OK, nevermind, you are right.
This is related to #17 -- but it really deserves a fresh discussion. Freezer is a great tool, and it almost replaces the extremely complex mental model of all the fluxes or whatever.
As said in #17, I agree that a general diff support would kill performance, but some support on top of the Freezer object should be possible.
In most cases, the application state object may be very fine-grained (and a mix of temporary (status messages etc.) and permanent state), but the updates will typically be very coarse-grained.
So, given this imaginary state object:
status
andsearchFilter
is just temporary view-stateuserRoles
are read-onlySo for updates I'm only interested in events from:
user.profile
;user.orders
;So, if you create some kind of wrapper that keeps a history of state changes, it should be possible to listen for these updates only by diffing only these two objects. And then maybe add undo/redo as an add-on.