## Tree 

```javascript
// State Tree itself should be normalized and lean towards flat (sort of like a traditional relational database)
//
{
  // Route Parameters
  params: {
    pageId: 1,
  },
  // Card Reducer
  cards: {
    1: {
      ...
    },
    2: {
      ...
    }
  },
  // Page Reducer
  pages: {
    1: {
      title: 'Some Page',
      cards: new Set(1, 2) // not JSON but important to leverage set for guaranteed uniqueness

    }
  }
}
```

## Selectors

You then use what is called a `selector` to render a page, or component, etc. The selector can be what you need for the whole UI or just a given component.

```javascript
const selectCurrentPage = (state) => {
  const page = state.pages[state.params.pageId];
  return {
    ...page,
    cards: page.cards.map((cardId) => state.cards[cardId])
  }
};
```

To create efficient selectors you can use memoization, see: https://github.com/reactjs/reselect (not coupled to React)

```javascript
// In this case the work of merging & mapping would be done once, no matter how many re-renders you caused. Truth is though in this case we are just passing around references which is exceptionally fast.
// This gives you a place to do efficient computations & derived data without a messing up your state tree.
// Important to use a memo with a cache size of 1
const selectCurrentPage = createSelector(
  selectPageByCurrentId,
  (page) => ({
    ...page,
    cards: page.cards.map((cardId) => state.cards[cardId])
  })
);
```

Something really dope about this pattern is that we return the same reference if nothing has changed and a new reference if something *has* changed. This means our UI framework can use reference semantics to know when to re-render instead of deep comparisons.

So instead of `deepEqual(one, two)` our UI tool can say `one !== two` and know when to re-render. One of the *many* benefits of immutability.


## Action Creators

Actions creators the things that provide actions for the tree can be effecient by using the tree's existing state, this is useful to avoid duplicate requests/work if something already exists in the tree

```javascript
const getPage = (id) => ((dispatch, getState) => {
  if (selectPageByCurrentId() !== null) return null; // We can short circuit since we have this data, we can be smart about how we do this to based on semantics around the data itself.
  fetch(`/page/${id}`)
    .then((response) => {
      dispatch({
        type: 'PAGE_LOAD',
        paylod: response.json()
      });
    }):
})
```