0.1.0 • Published 6 years ago

@loll/component v0.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

@loll/component

Universal component microlibrary. Can be used with any template-literal component library like @loll/h, bel, or hyp.

Install

npm i @loll/component --save

Usage

Create a component. h here can be any library:

// MyComponent.js
const component = require('component')

module.exports = component({
  render (props, state) {
    return h`
      <div>
        <h1>The count is 0</h1>
      </div>
    `
  }
})

Add state:

// MyComponent.js
module.exports = component({
  init (props, state) {
    this.state = {
      count: 0
    }
  },
  render (props, state) {
    return h`
      <div>
        <h1>The count is ${state.count}</h1>
      </div>
    `
  }
})

Add methods:

// MyComponent.js
module.exports = component({
  init (props, state) {
    this.state = {
      count: 0
    }
  },
  inc () {
    const render = this.setState(state => ({
      count: state.count + 1
    }))

    /*
     * Only updates when the return
     * from this.setState({})
     * is called
     */
    render()
  },
  render (props, state) {
    return h`
      <div>
        <h1>The count is 0</h1>

        <button onclick=${this.inc.bind(this)}>Up</button>
      </div>
    `
  }
})

Prevent updating. Think shouldComponentUpdate. The below will never update:

// MyComponent.js
module.exports = component({
  init (props, state) {
    this.state = {
      count: 0
    }
  },
  inc () {
    const render = this.setState(state => ({
      count: state.count + 1
    }))

    /*
     * Only updates when the return
     * from this.setState({})
     * is called
     */
    render()
  },
  update (props, state) {
    return false
  },
  render (props, state) {
    return h`
      <div>
        <h1>The count is 0</h1>

        <button onclick=${this.inc.bind(this)}>Up</button>
      </div>
    `
  }
})

Async actions and incremental rendering:

// MyComponent.js
module.exports = component({
  init (props, state) {
    this.state = {
      loading: false,
      posts: props.posts
    }
  },
  fetchMore () {
    // show a loading state while we fetch
    this.setState({ loading: true })()

    return fetch().then(posts => {
      this.setState({ loading: false, posts })
    })
  },
  render (props, { loading, posts }) {
    return h`
      <div>
        <h1>Posts</h1>

        ${loading ? h`
          <small>Posts are loading</small>
        ` : h`
          <div>
            ${posts.map(p => Post(p))}

            <button onclick=${this.fetchMore.bind(this)}>
          </div>
        `}
      </div>
    `
  }
})

Rendering in an App

Components built with @loll/component can be used just like any other component in your app.

// HomePage.js
const h = require('bel')
const MyComponent = require('./MyComponent.js')

module.exports = function HomePage (props) {
  return h`
    <div>
      ${MyComponent()}
    </div>
  `
}

Dependencies

  • nanomorph - Hyper fast diffing algorithm for real DOM nodes
  • nanoassert - Nanoscale assertion module.

MIT

0.1.0

6 years ago

0.0.1

6 years ago