Choo: Document components

Created on 4 Jun 2018  路  12Comments  路  Source: choojs/choo

Expected behavior

Since component support has landed in Choo, I should know how to use it without reading the code.

Actual behavior

There is no doc about components.

Most helpful comment

Yeah, actually docs about nanocomponent itsefl are fine, my concerns are the changes to the state in choo apps, the use of the cache for componenets... I'm not very clear how to use those

All 12 comments

There is some good info at the nanocomponent repo: https://github.com/choojs/nanocomponent/blob/master/README.md

I agree though, there should be some more choo specific info on components here.

Yeah, actually docs about nanocomponent itsefl are fine, my concerns are the changes to the state in choo apps, the use of the cache for componenets... I'm not very clear how to use those

Looking at the component cache code -- am I correct to assume that the cache is defined to store 100 entries (component instances)?

What happens when you have a page with more than 100 components? Does that mean that some of the components are going to be re-initialized after each render?

Or in case of 100 pages each containing 1 component. Only one component is displayed at one moment. Does that mean that all the houndred instances are stored in the cache even if they are not attached to dom?

Thanks!

That's right @lemmon. The idea is to offer a sensible default (100) which can be overridden with options (var app = choo({cache: 9999})). But if you're going to be creating a LOT of components for a very specific case, you'd instantiate a separate cache for that purpose, e.g.:

var html = require('choo/html')
var Cache = require('choo/component/cache')
var Component = require('choo/component')
var Item = require('./item')

module.exports = class List extends Component {
  constructor (id, state, emit) {
    super(id)
    this.cache = new Cache(state, emit, 9999)
  }

  update () {
    return true
  }

  createElement (items) {
    return html`
      <ul>
        ${items.map((item) => this.cache(Item, item.id).render(item))}
      </ul>
    `
  }
}

I think that, the cache management belongs to some sort of _advanced_ topic in the future components docs. I think a good TOC for component docs would be like

  1. Components
    1.1 Nanocomponent reference
    1.2 state.cache explained
    1.3 state.components explained
    1.4 Custom cache (advanced)

What do you think?

Thanks @tornqvist.

@YerkoPalma seems okay. I didn't even know there was state.components parameter.

This components cache got me thinking few days back, I know I am going off the topic here a bit, but I triet to implement a cache with no components limit. But instead a component would be removed from the cache whenever is unloaded from DOM.

I put together a small example:
http://component.lemmonjuice.com/
https://github.com/lemmon/choo-component-container/blob/master/src/container.js

@lemmon very cool! I think something like that would avoid ever needing custom cache instances. I wonder if it can be done without overwriting the component's unload handler somehow :thinking:

That's funny, I was actually exploring a similar idea in the components thread (warning: super long thread!) but figured that the performance overhead of attaching on-load listeners to all components would outweigh the gain. It's also a quite nice feature to have component state persist between unload/load. But I bet there are situations where an unload cache makes more sense than an LRU cache.

But the the API totally allows you to use your own cache in place of the default nanolru. The cache option can be a number (number of instances in the LRU cache) or an object which has the same signature as nanolru (synchronous get and set methods).

var app = choo({cache: new MyCustomComponentCache()})

You might be right about the performance, didn't check that yet. Maybe if some kind of load/unload observer was baked in directly into Nanomorph. However it would not be working with direct DOM manipulation.

+1

It would be great for some documentation on cache, components and how these relate to each other, especially across navigations in the router.

on-load uses a single shared mutation observer, I think. The overhead should not be that big. Im sure there would be other difficulties though, as always with those things

Totally with you on that. There are some unexpected behaviour in my app tho.

Trouble I'm having with router, cache and components is that the component arguments end up as undefined when the route is changed, as these arguments are passed down from the route handler. I thought the cache should keep these data between routes. I must be missing something, because this just doesn't seem logical to me.

Was this page helpful?
0 / 5 - 0 ratings