anywhichway / jsxdirect

A browser based JSX transpiler with automatic support for React, preact, and hyperapp.
MIT License
23 stars 1 forks source link

contexts are messed up for react 6.7.0 hooks #3

Closed vans163 closed 5 years ago

vans163 commented 5 years ago

This does not work. Function setCount cannot be found.

function Clock() {
    const [count, setCount] = React.useState(0);

    return jsx(`
        <div>
            <button key=1 onClick={()=> setCount(1)}>hi hi hi ${count}</button>
        </div>
    `);
}

This works.

function Clock() {
    const [count, setCount] = React.useState(0);

    return React.createElement("button", {onClick: ()=> setCount(1)}, `hii ${count}`);
}
anywhichway commented 5 years ago

@vans163 To get this to work may require use adding code to support context passing, please look at the below and tell me if it would be acceptable:

function Clock() {
    const [count, setCount] = React.useState(0);

    return jsx(`
        <div>
            <button key=1 onClick={()=> setCount(1)}>hi hi hi ${count}</button>
        </div>
    `{ctx:{setCount}});
}
vans163 commented 5 years ago

Seems good to me, only other alternative I see is somehow extracting automatically whats inscope and passing it as part of the ctx.

anywhichway commented 5 years ago

Doing the extraction reliably would probably require a full blown parser which is beyond the scope of what I am trying to accomplish with the library. I will try adding the context passing capability.

anywhichway commented 5 years ago

@vans163 I have posted v0.0.9 with what may just be a partial fix. It is not clear the count variable will remain in scope for the function. However, it appears the correct VDOM is getting generated. I have not fully tested because it looks like the hooks you are using are an alpha feature for React and I have not taken the time to build an environment to support it. Give things a shot and let me know how it works out,

vans163 commented 5 years ago

@anywhichway sweet gonna test. And yes hooks are currently Alpha but they are here to stay. It allows you to actually write functional code instead of object oriented code plus nicely simplifies and decouples complex components and removes the need for Redux. (you can write hooks that replace Redux functionality but official React examples dont show how)

vans163 commented 5 years ago

I think regardless a more robust solution is needed. Is the global scope inscope of the jsx call? Or just 'this'?

For example https://github.com/anywhichway/jsxdirect/issues/4, this issue, forces writing out every tag fully into the JSX, a deference cannot be used.

var TabPane = antd.Tabs.TabPane;
jsx(`<TabPane/>`)

Not possible due to TabPane not in scope.

anywhichway commented 5 years ago

@vans163 Up to this point, scope available inside jsx has effectively been the scope available for call to Function which is JavaScript built-ins plus whatever is passed to it via the ctx in the second argument to jsx. In v0.0.11 we have expanded this to include the scope available to the defining of jsxdirect which is done via the convention (function() { ... jsxdirect code ...}).call(this) in the file jsxdirect.js. In general, it will be the global scope; although a dynamic loading and interpreting of jsxdirect.js could muck it up.

In your example is antd.Tabs.TabPane effectively a custom element? If so, scope is not the issue. With tlxdirect you would currently have to declare it as such, e.g. customElements.define("TabPane",TabPane). However, the customElement spec requires dashed names; hence, it still would not work. The code would have to be:

var TabPane = antd.Tabs.TabPane;
customElements.define("a-TabPane",TabPane); // requires polyfill in Edge
jsx(`<a-TabPane></a-TabPane`)

If TabPane is not a customElement, then the above will not work and you would need a wrapper function around TabPane that returned something that behaved like a customElement.

var TabPane = antd.Tabs.TabPane;
customElements.define("a-TabPane",ToCustomComponent(TabPane));
jsx(`<a-TabPane></a-TabPane`)

I do not anticipate we would be able to enhance 'jsxdirect' to support the resolution of a variable into a tag. This would require knowing how to generate valid HTML for the variable. Although you are using React and most people using JSX are using React, as far as I know it is not supposed to be strictly a React oriented processor. Hence, other users of jsxdirect would have different expectations about what could be handled. Finally, and most relevantly, we don't have the resources to take this type of change on.

Please let us know if you find a situation in which global scope is no available to jsx independent of resolving variables into tag names and it will be looked into.