Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose pragma option for createVNode name #43

Closed
zerkalica opened this issue Mar 27, 2017 · 4 comments
Closed

Expose pragma option for createVNode name #43

zerkalica opened this issue Mar 27, 2017 · 4 comments

Comments

@zerkalica
Copy link
Contributor

zerkalica commented Mar 27, 2017

In babel-plugin-transform-react-jsx i can do:

{
  "plugins": [
    ["transform-react-jsx", {
      "pragma": "dom" // default pragma is React.createElement
    }]
  ]
}

Please add same thing to your plugin.

In reactive-di i use dependency injection techiques and my components are independed from react, inferno, whatever. They are really pure, without framework bindings. Passing createVNode to components also clearly solves context inheritance problem. It's works like hierachical dependency injectors in angular2.

var createVNode = Inferno.createVNode;

function Hello(_ref, _ref2, createVNode) {
    var text = _ref.text;
    var user = _ref2.user;

    var set = new _src.BaseSetter(user).create(_src.BaseSetter.createEventSet);
    return createVNode(2, 'div', null, [createVNode(2, 'h1', null, ['Hello ', user.name]), createVNode(512, 'input', {
        'value': user.name
    }, null, {
        'onInput': set.name
    })]);
}

I use createVNode only as interface for interfactions with di container. It's format is better optimized than createElement. But i don't want to create function createVNode instead of delegating object with method.

In di core binded to this, it's not good:

createVNode: CreateVNode = (
    ) => {...}

I want to pass di core object instead of function, to do something like this:

function Hello(_ref, _ref2, t) {
    return t.h(2, 'div', null, [t.h(2, 'h1', null, ['Hello ', user.name]), t.h(512, 'input', {
        'value': user.name
    }, null, {
        'onInput': set.name
    })]);
}
@Havunen
Copy link
Member

Havunen commented Mar 27, 2017

We can add that, but I wonder what is the use case behind this? there is Inferno.options.createVNode if you want to hook into it?

@zerkalica
Copy link
Contributor Author

zerkalica commented Mar 27, 2017

In short.

  1. Abstraction from inferno, react, etc, my component knowns about createVNode interface, not realization.
    Look at hello example In entry point:
//..
const di = new DiFactory({
    createVNode: infernoCreateVNode,
    component: createReactRdiAdapter(Component)
})
    .create()

render(
    di.createVNode(16, Hello, {text: 'test'}),
    window.document.getElementById('app')
)

I can adopt react.createElement to createVNode without recompiling my components.

  1. Dependency injection. My components are different from react. First arguments - public props. Second - component context (its internal dependencies, state, etc). My createVNode pass them to second argument.
function Hello(
    {text}: {
        text: string;
    },
    {user}: {
        user: User;
    }
) {
    const set = new BaseSetter(user).create(BaseSetter.createEventSet)
    return <div>
        <h1>Hello {user.name}</h1>
        <input value={user.name} onInput={set.name} />
    </div>
}

babel-plugin-metadata extract types info from second argument, dependency injection resolves them and di.createVNode is a bridge to di, that wraps component to something this:

class HelloWrapped extends Inferno.Component {
  render() {
    return Hello(this.props, di.state, Inferno.createVNode)
  }
}
  1. DI is like docker container on top of component. Each component can create new di container, which inherits parent state.

I can't use createVNode as singletone from imports. In example below component B has an User state from root container const di = new DiFactory( .

"A" has shallow copy of root di container with own separate copy of User. User in A !== User in B.

For hierachical injectors feature i need to create own copy of createVNode for A. createVNode in A !== createVNode in B.

It's works like hierachical dependency injectors in angular2.

class User {}

function A(props: {}, state: {user: User;}, createVNode: CreateVNode) {
  return <div/>
}
component({
  register: [User]
})(A)

function b(props: {}, state: {user: User;}, createVNode: CreateVNode) {
  return <A/>
}

const di = new DiFactory({
    createVNode: infernoCreateVNode,
    component: createReactRdiAdapter(Component)
})
    .create()

Inferno.render(
    di.createVNode(16, Hello, {text: 'test'}),
    window.document.getElementById('app')
)

More complex todo example, EditingTodo and TodoViewService created per each TodoView.

@Havunen
Copy link
Member

Havunen commented Mar 27, 2017

I see, thanks for comment. Can you send PR to add this feature, it should be trivial task.

@Havunen
Copy link
Member

Havunen commented Mar 27, 2017

Merged and released 3.1.0. Thank you @zerkalica

@Havunen Havunen closed this as completed Mar 27, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants