S
SolidJS4mo ago
gerard

Pass props from Component to props.children

function Child (props) { return <div class={props.class}>child</div> }

function Parent (props) {
// I want parent to be able to customize the props passed to children here
// like for example the css class
return <div>{ props.children }</div>
}

function App () {
return (
<Parent>
<Child />
</Parent>
)
}
function Child (props) { return <div class={props.class}>child</div> }

function Parent (props) {
// I want parent to be able to customize the props passed to children here
// like for example the css class
return <div>{ props.children }</div>
}

function App () {
return (
<Parent>
<Child />
</Parent>
)
}
Things that I have tried and do not work:
function Parent (props) {
return <div>{ props.children({ class: "test" }) }</div>
}
function Parent (props) {
return <div>{ props.children({ class: "test" }) }</div>
}
function Parent (props) {
return <div><Dynamic component={props.children} class="test" /></div>
}
function Parent (props) {
return <div><Dynamic component={props.children} class="test" /></div>
}
8 Replies
Danny
Danny4mo ago
Since the component Child is already called when you do <Child /> you cannot pass any props to it. You could instead pass a function and then props.children would be that function that you can call and pass the props.
Maciek50322
Maciek503224mo ago
If you only want to change class of the Child, which returns the html element, you can change it no problem with this: https://docs.solidjs.com/reference/component-apis/children like here https://www.solidjs.com/tutorial/props_children Also what's stopping you from doing:
function Parent (props) {
// here control props of Child however you want
return <div>
<Child />
</div>
}
function Parent (props) {
// here control props of Child however you want
return <div>
<Child />
</div>
}
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
Maciek50322
Maciek503224mo ago
with the children api I linked you can change only html properties, not the props of function component
ChrisThornham
ChrisThornham4mo ago
I've always done it like this. Here's a custom button that you can use as a child.
interface ChildButtonProps {
btnText: string;
btnType?: string;
btnWidth?: string;
btnSize?: string;
}

export default function ChildButton(props: ButtonProps) {
// VARIABLES ========================================================
const type = props.btnType ? props.btnType : "btn-primary";
const width = props.btnWidth ? props.btnWidth : "";
const size = props.btnSize ? props.btnSize : "";
const classes = `btn ${type} ${width} ${size}`;

// TSX ==============================================================
return <button class={classes}>{props.btnText}</button>;
}
interface ChildButtonProps {
btnText: string;
btnType?: string;
btnWidth?: string;
btnSize?: string;
}

export default function ChildButton(props: ButtonProps) {
// VARIABLES ========================================================
const type = props.btnType ? props.btnType : "btn-primary";
const width = props.btnWidth ? props.btnWidth : "";
const size = props.btnSize ? props.btnSize : "";
const classes = `btn ${type} ${width} ${size}`;

// TSX ==============================================================
return <button class={classes}>{props.btnText}</button>;
}
Then you can customize this child in a parent like this.
export default function Parent() {
// TSX ==============================================================
return (
<>
<ChildButton
btnText="Press Me"
btnType="btn-Warning"
btnWidth="w-44"
btnSize="btn-sm"
/>
</>
);
}
export default function Parent() {
// TSX ==============================================================
return (
<>
<ChildButton
btnText="Press Me"
btnType="btn-Warning"
btnWidth="w-44"
btnSize="btn-sm"
/>
</>
);
}
Hope that helps.
Madaxen86
Madaxen864mo ago
As said before. The children are already rendered when the parent function is executed. There is no cloneElement like in react. So you have to figure out a way to change the props from within the children. One way would be a context where you pass props in the parent and consume the context in the Child component(s). And what also comes in handy is the Dynamic component which gives you the ability to setup all the props for the Child component and also gives users the ability to use any html element or component through the as prop.
mrVinicius
mrVinicius4mo ago
What about child accepting an class and returning an element? I've run into a similar issue.
export default (className?: string) => {
return (
<svg
class={`w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white ${className || ''}`}>/*deleted for reability*/</svg>
)
}

type NavProps = {
name: string;
route: string;
icon?: (className?: string) => JSXElement;
}

const Nav = (props: NavProps) => {
const sidenavCtx = useSidenav();

if (sidenavCtx.navs.has(props.name)) {
throw new Error('Nav name must be unique')
} else sidenavCtx.navs.add(props.name);

return (
<li>
<A
href={props.route}
class={`flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 group`}
>
{props.icon?.("classes i wish to pass")}
<span class="ml-3">{props.name}</span>
</A>
</li>
)
};
export default (className?: string) => {
return (
<svg
class={`w-5 h-5 text-gray-500 transition duration-75 dark:text-gray-400 group-hover:text-gray-900 dark:group-hover:text-white ${className || ''}`}>/*deleted for reability*/</svg>
)
}

type NavProps = {
name: string;
route: string;
icon?: (className?: string) => JSXElement;
}

const Nav = (props: NavProps) => {
const sidenavCtx = useSidenav();

if (sidenavCtx.navs.has(props.name)) {
throw new Error('Nav name must be unique')
} else sidenavCtx.navs.add(props.name);

return (
<li>
<A
href={props.route}
class={`flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700 group`}
>
{props.icon?.("classes i wish to pass")}
<span class="ml-3">{props.name}</span>
</A>
</li>
)
};
REEEEE
REEEEE4mo ago
Dynamic but that's fine too
Brendonovich
Brendonovich4mo ago
combining function-as-child and dynamic should work?
function Child (props) {
return <div class={props.class}>child</div>
}

function Parent() {
return (
<div>
<Dynamic component={props.children} class="..." />
</div>
);
}

function App () {
return (
<Parent>
{props => <Child {...props} />}
</Parent>
)
}
function Child (props) {
return <div class={props.class}>child</div>
}

function Parent() {
return (
<div>
<Dynamic component={props.children} class="..." />
</div>
);
}

function App () {
return (
<Parent>
{props => <Child {...props} />}
</Parent>
)
}
Want results from more Discord servers?
Add your server