Yomguithereal / baobab-react

React integration for Baobab.
MIT License
310 stars 38 forks source link

Accessing cursors in component #112

Open ruscoder opened 8 years ago

ruscoder commented 8 years ago

In version 1.x we could access cursor instance via this.cursors. Now, it was removed from the documentation. Why? And how to access to cursor instance when we use HoC?

Yomguithereal commented 8 years ago

This was removed to enforce architectural good practices and to boost performance. You are now required to use actions to edit the tree.

aconran commented 7 years ago

Was searching on this for a little while; Would be good to have a section on differences between 1.x and 2.x outlining the major changes.

1) Swapping the arguments on branch/tree 2) Removing the wrapper components 3) Accessing cursors via context

jatins commented 7 years ago

This was removed to enforce architectural good practices and to boost performance

@Yomguithereal Could you elaborate on the performance aspect? Is the not performant to pass cursors around as props?

Yomguithereal commented 7 years ago

You should avoid to create too many cursors (say, creating one cursor per element of a long list is not advisable). Because even if they are cached as singleton per path, you still register some listeners and observers.

Is the not performant to pass cursors around as props?

This is not really an issue but I don't really see why you would like to do that. In my experience, components just want to consume data from your tree and trigger some actions but not having control over the underlying cursors.

In this regard it's actually quite similar to redux etc.

jatins commented 7 years ago

This is not really an issue but I don't really see why you would like to do that

So, let's say:

  1. I pass around cursors as props in components
  2. Somewhere up in component tree, I attach an update listener to a parent cursor like this:
parentCursor.on('update', function () {
  this.setState({...})
)

Then anytime, I call cursor.set() in any child component (which takes some child cursor as prop), the event handler will fire, and re-render the tree because of setState.

Although, if some child component wants to modify data up the tree (any data not passed to it as a prop), then yes, I'd need to trigger some actions.)

Yomguithereal commented 7 years ago

Sure. But this is more or less what the baobab-react helpers handle for you.

jatins commented 7 years ago

The problem I ran into with baobab-react is that if I need to modify a node in tree, the action handlers need to know the entire path of the node from the root.

For example, if we look at actions.js in this, we are directly doing a tree.push('colors', color). So, if colors were, say, four level deep, that'd become a problem.

Redux seems handles that by reducer composition (combineReducers).

Is there a better way to handle that in baobab-react ?

Yomguithereal commented 7 years ago

Usually, I do the following: I often split my action files hierarchically and they all have sets of cursor paths that the actions can use. Or I use function composition to abstract this issue. Another solution is to pass the paths as the actions' arguments but I am not so found of this.

Redux is already more abstract and indeed handle this somewhat using combineReducers but lacks in flexibility, notably when you need to burst out of this abstraction (two sibling reducers handling somewhat dependent state is a bit of a pain in redux for instance).