Issue
I'm trying to create a component where certain HTMLElements or ReactComponents are passed to it like this:
<ContentList>
<span>Hi</span> // Passed child No. 1
<span>Hi2</span> // Passed child No. 2
<CustomComponent prop1={}></CustomComponent> // Passed child No. 3
</ContentList>
Then, it will render the passed children into this structure:
render() {
let content: React.ReactNode = this.props.children;
//----------------------
//Desired Process goes here
//----------------------
return (
<>
<section className={styles.list}></section>
<section className={styles.contentPanel}></section>
</>
);
}
Where the first section is supposed to be a content list and the second section is going to be the rendered ReactComponents and HTMLElements. My question is How am I supposed to work with props.children (aka content) as an array? I tried to search for it online but there is no solid guide out there. Basically I want to do something like this:
let content: React.ReactNode = this.props.children;
// Creating relevant anchor for each content
let list = content.map((child, i) => {
return (<a className="content-link" href={"#"+child.id}>{child.title}</a>)
});
// Rendering each content after wrapping them inside proper div
let contents = content.map((child, i) => {
return (<div className="content">{child}</div>)
});
return (
<>
<section className={styles.list}>{list}</section>
<section className={styles.contentPanel}>{contents}</section>
</>
);
Solution
The Typescript compiler is super strict on variable type in declaration and assignment but I managed to get it working by the following process:
render() {
let content: React.ReactNode = this.props.children;
let list: Array<JSX.Element> = [], // #1
contents: Array<JSX.Element> = []; // #1
if (this.props.children !== undefined && this.props.children !== null) {
if (Array.isArray(content)) { // #2
let arr: Array<any> = content; // #3
list = arr.map((child, i) => {
return (
<a
className={styles.contentAnchor}
href={"#content_" + child.props.id}
>
{child.props.title}
</a>
);
});
contents = arr.map((child, i) => {
return (
<div
id={"content_" + child.props.id}
className={styles.contentWrapper}
>
{child}
</div>
);
});
}
}
return (
<>
<section className={styles.list}>{list}</section>
<section className={styles.contentPanel}>{contents}</section>
</>
);
}
The actual key lines that were missing from the start are the ones I marked with #
Answered By - Andrew Sharifikia
Answer Checked By - - Mary Flores (ReactFix Volunteer)