Reputation: 882
I have a repository with Stencil.js and I create a couple of web components, nested and working in Stencil development environment. in example I have a parent component that use a child component:
import { Component, h, Prop, State } from "@stencil/core";
@Component({
tag: "parent-component"
})
export class MyParent {
@Prop() carddata: any;
render() {
return (
<div>
<child-component
carddata={this.carddata}
/>
</div>
);
}
}
this is the child component:
import { Component, Prop, h } from "@stencil/core";
@Component({
tag: "child-component"
})
export class MyChild {
@Prop() carddata: any;
renderItems(items: string[]): string {
let newString = "";
items.map((item: string) => {
newString = newString.concat(item, ", ");
});
return newString.substr(0, newString.length - 2);
}
render() {
const { items } = JSON.parse(this.carddata);
return (
<p>
Items: <b>{this.renderItems(items)}</b>
</p>
);
}
}
When I build and use the package created in another repository (React app) I have errors on renderig the web components. This is the React Component where I use the web component:
[...]
import * as cardData from "./card-mock-data.json";
[...]
render() {
return (
<Wrap>
<parent-component
carddata={JSON.stringify(cardData)}/>
</Wrap>
);
}
[...]
And the error is TypeError: Cannot read property 'map' of undefined
. It's hard to debug, because is compiled code, but the error seems to refers to this piece of (compiled) code:
ChildComponent.prototype.renderItems= function (items) {
var newString = "";
items.map(function (item) {
newString = newString.concat(item, ", ");
});
return newString.substr(0, newString.length - 2);
};
Maybe I'm wrong with something, Can I pass data to nested component using only the parent tag in React? Maybe I'm missing some "parsing" step?
Thanks for your help
EDIT: add cardData snippet:
{
"id": "invito-biologia-blu",
"titolo": "Il nuovo invito alla biologia blu",
"img": "http://media.curtisinvitoblu.bedita.net/a1/40/curti_a140cb3359b7611d84f80e384d2fb49b/curtis_plus-1A_320x_71bc3567ace1ff728caef1b381d7535b.png",
"tags": ["Polimeri", "biochimica", "biotecnologie", "sostenibilità"],
"autori": ["Helena Curtis", "Sue Barnes", "Alicia Mastroianni"],
"anno": 2017,
"actions": ["Leggi sul browser", "Sito e risorse del libro", "ZTE"]
}
when I log cardData in render() I have this:
Module {default: {…}, __esModule: true, Symbol(Symbol.toStringTag): "Module"}
Upvotes: 1
Views: 2148
Reputation: 1037
The problem is, that React 16 passes all data to Custom Elements as HTML attributes. And it just doesn't work for objects or arrays.
More info: https://custom-elements-everywhere.com/libraries/react/results/results.html
The good news is that they may fix this in React 17: https://github.com/facebook/react/issues/11347
To fix this now, you will need to pass the data as properties.
Take a look at the Ionic team solution here: https://github.com/ionic-team/ionic/blob/master/react/src/components/createComponent.tsx
Upvotes: 1