stencil icon indicating copy to clipboard operation
stencil copied to clipboard

Unable to pass JSX between classes in the same library

Open AmitMY opened this issue 4 years ago • 8 comments

Stencil version:

 @stencil/[email protected]

I'm submitting a:

[x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior: I have a component that can be rendered either on a canvas, or an svg. To deal with that, I have created two classes called:

  • SVGRenderer
  • CanvasRenderer Which are not components, and are just tsx classes.

The canvas render method for example returns:

return (
    <canvas width={500} height={500} />
)

And the component just calls canvasRenderer.render().

The HTML produced is:

<canvas>

Expected behavior: The HTML produced should be:

<canvas width="500" height="500">

Other information: This is the case even if the renderer classes are in the same file of the component itself.

Might be a duplicate of #2884, but I think quite important to fix.

AmitMY avatar Jul 23 '21 11:07 AmitMY

Hey @AmitMY 👋

Would it be possible for you to provide us with a minimal reproduction? While I think there's some good detail in this ticket, having an example that's whittled-down to the smallest reproduction case would help us greatly in figuring out what's going on here.

rwaskiewicz avatar Jul 28 '21 12:07 rwaskiewicz

Alright.

  1. Started a new project, of type component - https://github.com/AmitMY/stencil-component-jsx-test/
  2. Only changed this file
  3. I now expect to see an image with an src, however, I see no attributes: image

AmitMY avatar Jul 28 '21 12:07 AmitMY

Just a guess - but I think because MyRenderer is just a plain class not a @Component, it probably doesn't handle JSX objects the same way. You might be able to use a Functional component instead:

const MyRenderer = props => <img src="https://explorit.ch/wp-content/uploads/2019/10/placeholder.png" />;

...

render() {
    return <MyRenderer />;
}

gtranter avatar Jul 28 '21 17:07 gtranter

my actual MyRenderer is quite complex, so this won't really work for me (a bit messy)

AmitMY avatar Jul 28 '21 21:07 AmitMY

@AmitMY In your actual MyRenderer component, do you have props defined with the @Prop() decorator? Sorry, might be a silly question, but I don't see any mention in this thread or in your source code of the prop decorator.

It's my understanding that prop decorators are required in order to pass values to it. Based on the file you linked here, I'm not sure how your components know how to handle the values that are passed otherwise.

Are you using @Prop() somewhere that I don't see? Are you familiar with prop decorators?

KHCode avatar Jul 30 '21 22:07 KHCode

@KHCode while in the index.html some props are assigned to my-component, they are ignored, becasue I removed the @Props from the component.

MyRenderer is just a class, not a component. I don't care for change detection here, nor do I care for the value of the props of my-component. The issue is that if a @Component render function calls a function from a different class, the jsx elements are passed correctly, and the jsx attributes are not.

AmitMY avatar Jul 31 '21 05:07 AmitMY

Hey there, thank you for the patience getting back to you. The new team is getting started and we're working through the backlog now.

We're still looking into this. Thank you for the patience!

splitinfinities avatar Aug 10 '21 18:08 splitinfinities

Hi @AmitMY , @splitinfinities and others. I know what fixes this. I have been struggling to know why it fixes but ok.

SInce you said Which are not components, and are just tsx classes.

Which means some sort of functional components/not components.

When you use any attribute,id,events whatever inside functional component, you need to define a dummy div tag something like

randomTag = <div width ={{}} height={{}}></div>

inside your class component where you had imported your template from. It will show attributes then.

I know this sounds strange. That's why I raised it here as well https://github.com/ionic-team/stencil/issues/3194 hack that's worked https://github.com/ionic-team/stencil/issues/3194#issuecomment-999414744

pranav-js avatar Dec 24 '21 09:12 pranav-js