Yomguithereal / baobab-react

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

[hooks] Allow changing cursor path dynamically #135

Open rasendubi opened 4 years ago

rasendubi commented 4 years ago

With the current implementation, when cursors changes, a new watcher is created and we subscribe to "update" event. The issue is, if the value under new path never changes, useBranch will always return the value from the previous path.

In example below (from documentation), changing alternative prop will not change colors after first render.

import React, {Component} from 'react';
import {useBranch} from 'baobab-react/hooks';

const List = function(props) {
  // Using a function so that your cursors' path can use the component's props etc.
  const {colors} = useBranch({
    colors: [props.alternative ? 'alternativeColors' : 'colors']
  });

  function renderItem(color) {
    return <li key={color}>{color}</li>;
  }

  return <ul>{colors.map(renderItem)}</ul>;
}

export default List;

Fix this by re-fetching the current value in the useEffect.

Another issue is that with the current examples, selectors changes on every render. Passing in an object or function inline will create a new instance of object on every render, triggering watcher re-creation.

With the fix above, that leads to an infinite loop:

Fix this by adding a deps argument that should hold an array of dependencies to trigger re-subscription. The default value is now an empty array to break the infinite loop and be more backward-compatible.

Another alternative is to use useMemo to memoize selectors in examples, but that is overly-verbose and would require a lot of migration effort for users.

Yomguithereal commented 4 years ago

@arnaudmolo any insight? I am a bit out of the water with hooks.