Yomguithereal / baobab

JavaScript & TypeScript persistent and optionally immutable data tree with cursors.
MIT License
3.15k stars 116 forks source link

Cursor that get notified if object/collection has changed, not its nested elements #451

Open NickAb opened 8 years ago

NickAb commented 8 years ago

In example https://github.com/Yomguithereal/baobab#events it says that both 'users' and ['users', 'john'] cursors will be notified if John's firstname is changed. Is there a way to notify ['users', 'john'] only and not 'users'? Same for collections, if I have a list of users, how can I bind to change of list (item added, item removed, list replaced), not its nested elements?

My use case is: I have a component that is bound to collection or object (that represents tree as nested ojbects), I want parent component to get re-rendered (notified of change) only when collection or object changes number of items/keys or gets replaced, not when children props values are changed, as I am going to have each child as a component bound directly to corresponding item in the tree.

If parent component gets render notification, then it causes whole tree to be re-rendered, which is very slow as it has quite a few elements.

Here is a snippet from README with the example:

var tree = new Baobab({
  users: {
    john: {
      firstname: 'John',
      lastname: 'Silver'
    },
    jack: {
      firstname: 'Jack',
      lastname: 'Gold'
    }
  }
});

// And the following cursors
var usersCursor = tree.select('users'),
    johnCursor = usersCursor.select('john'),
    jackCursor = usersCursor.select('jack');
...
// But if we update only john
johnCursor.set('firstname', 'John the third');
// Only the users and john cursors will be notified
hscheckenbacher commented 8 years ago

This is as expected since the tree is immutable, meaning an update to a child will also yield a new Object reference for the parent but the child that wasn't modified is re-referenced in the new parent under the same address.

Zache commented 8 years ago

I've had similar problems that I solved letting the child components be Branches with dynamic cursors. But I suspect immutability and purity of the tree will prevent you from doing what you want Den 3 jun 2016 16:58 skrev "Nick Abalov" notifications@github.com:

In example https://github.com/Yomguithereal/baobab#events it says that both 'users' and ['users', 'john'] cursors will be notified if John's firstname is changed. Is there a way to notify ['users', 'john'] only and not 'users'? Same for collections, if I have a list of users, how can I bind to change of list (item added, item removed, list replaced), not its nested elements?

My use case is: I have a component that is bound to collection or object (that represents tree as nested ojbects), I want parent component to get re-rendered (notified of change) only when collection or object changes number of items/keys or gets replaced, not when children props values are changed, as I am going to have each child as a component bound directly to corresponding item in the tree.

If parent component gets render notification, then it causes whole tree to be re-rendered, which is very slow as it has quite a few elements.

Here is a snippet from README with the example:

var tree = new Baobab({ users: { john: { firstname: 'John', lastname: 'Silver' }, jack: { firstname: 'Jack', lastname: 'Gold' } } });

// And the following cursors var usersCursor = tree.select('users'), johnCursor = usersCursor.select('john'), jackCursor = usersCursor.select('jack'); ... // But if we update only john johnCursor.set('firstname', 'John the third'); // Only the users and john cursors will be notified

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Yomguithereal/baobab/issues/451, or mute the thread https://github.com/notifications/unsubscribe/ADYLwIO6ypfs-AzZRqLmhBX5MNXPWGU4ks5qIEEKgaJpZM4ItnXS .