Skip to content

Discussion: Framework Agnostic Stateless Function Components #5

@dustinspecker

Description

@dustinspecker

Just some brainstorming, but I happily welcome all input.

dscript is currently a framework agnostic hyperscript implementation.

A few folks are already thinking about how it can be used to create framework agnostic stateless components, which sounds awesome.

Unfortunately, there is not a standard for args passed to a render method in components. For example, React's function components are passed a props object, while Deku's function components are passed a model object with a props property.

Proposing the idea of making mapModelToReact/mapModelToDeku/etc to handle this conversion so maintainers can create framework agnostic components.

I'm leaning towards something like:

// framework agnostic component
import dscript from 'dscript'

export default (renderer, mapModelToFramework) => model => {
  // maintainer wants to develop as if it were React
  const props = mapModelToFramework(model)
  // maintainer wants to develop as if it were Deku
  const {attributes, children, props} = mapModelToFramework(model)

  const {div, li, ul} = dscript(renderer)
  return (
    div('.container', [
      ul(
        props.items.map(item =>
          li([item.name])
        )
      )
    ])
  )
}

My main concern is this gets very hairy for consumers of framework agnostic components.

import {createElement} from 'react'
import {mapModelToReact} from 'dscript-model-mapper'
import originalComponent from 'framework-agnostic-component'

const myFrameworkComponent = originalComponent(createElement, mapModelToReact)

export default myFrameworkComponent

We can move most of the boilerplate to other modules, but I think it will still feel awkward for consumers.

EDIT:

I believe this can all be simplified to:

// framework agnostic component
import dscript from 'dscript'
import {mapModelToDeku, mapModelToReact} from 'dscript-model-mapper'

export default renderer => model => {
  // maintainer wants to develop as if it were React
  const props = mapModelToReact(model)
  // maintainer wants to develop as if it were Deku
  const {attributes, children, props} = mapModelToDeku(model)

  const {div, li, ul} = dscript(renderer)
  return (
    div('.container', [
      ul(
        props.items.map(item =>
          li([item.name])
        )
      )
    ])
  )
}
import {createElement} from 'react'
import originalComponent from 'framework-agnostic-component'

const myFrameworkComponent = originalComponent(createElement)

export default myFrameworkComponent

I think only the originalComponent should need to map the model and this starts to look better for consumers already.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions