S
SolidJS•10mo ago
Mimikku

memo with dynamic props pass

am I doing something heavily retarded? I find myself doing this pattern a lot to enforce that props item is subscribed to
export interface AccordionProps {
items: AccordionItem[];
class?: string;
}

const Accordion = (props: AccordionProps) => {
const items = createMemo(
on(
() => props.items,
items => assignPaths(items),
),
);

return (
<ul class={cx('flex flex-col h-full overflow-auto px-2', props.class)}>
<For each={items} children={Item} />
</ul>
);
};
export interface AccordionProps {
items: AccordionItem[];
class?: string;
}

const Accordion = (props: AccordionProps) => {
const items = createMemo(
on(
() => props.items,
items => assignPaths(items),
),
);

return (
<ul class={cx('flex flex-col h-full overflow-auto px-2', props.class)}>
<For each={items} children={Item} />
</ul>
);
};
Or should I do something entirely else?
const items = createMemo(
on(
() => props.items,
items => assignPaths(items),
),
);
const items = createMemo(
on(
() => props.items,
items => assignPaths(items),
),
);
It just seems "Funny" I mean I could also use
const Accordion = (props: AccordionProps) => {
return (
<ul class={cx('flex flex-col h-full overflow-auto px-2', props.class)}>
<For each={assignPaths(props.items)} children={Item} />
</ul>
);
};
const Accordion = (props: AccordionProps) => {
return (
<ul class={cx('flex flex-col h-full overflow-auto px-2', props.class)}>
<For each={assignPaths(props.items)} children={Item} />
</ul>
);
};
4 Replies
REEEEE
REEEEE•10mo ago
can't you just do
const items = createMemo(() => assignPaths(props.items))
const items = createMemo(() => assignPaths(props.items))
?
Mimikku
MimikkuOP•10mo ago
it does work in this case, but in such other example
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';

export interface ButtonIconProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
size?: ButtonSize;
icon: IconName;
iconclass?: string;
variant?: 'text' | 'contained';
active?: boolean;
cross?: boolean;
}

const keys = [
'iconclass',
'icon',
'active',
'size',
'class',
'children',
'variant',
'active',
'cross',
] satisfies (keyof ButtonIconProps)[];
const initial = { variant: 'contained', size: 'md' } satisfies Partial<ButtonIconProps>;
export const ButtonIcon = (props: ButtonIconProps) => {
const [local, $] = splitProps(mergeProps(initial, props), keys);

const Cross = createMemo(() => () => {
if (local.cross)
return (
<Icon
size={local.size}
class="stroke stroke-accent-8 w-max -rotate-45 absolute pointer-events-none"
name="CgBorderStyleSolid"
/>
);

return null;
});

return (
<button ...>
<Dynamic component={Cross()} />
...
</button>
);
};
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';

export interface ButtonIconProps extends JSX.ButtonHTMLAttributes<HTMLButtonElement> {
size?: ButtonSize;
icon: IconName;
iconclass?: string;
variant?: 'text' | 'contained';
active?: boolean;
cross?: boolean;
}

const keys = [
'iconclass',
'icon',
'active',
'size',
'class',
'children',
'variant',
'active',
'cross',
] satisfies (keyof ButtonIconProps)[];
const initial = { variant: 'contained', size: 'md' } satisfies Partial<ButtonIconProps>;
export const ButtonIcon = (props: ButtonIconProps) => {
const [local, $] = splitProps(mergeProps(initial, props), keys);

const Cross = createMemo(() => () => {
if (local.cross)
return (
<Icon
size={local.size}
class="stroke stroke-accent-8 w-max -rotate-45 absolute pointer-events-none"
name="CgBorderStyleSolid"
/>
);

return null;
});

return (
<button ...>
<Dynamic component={Cross()} />
...
</button>
);
};
It fails, it does not recognize change within that memo
REEEEE
REEEEE•10mo ago
Why not just use a Show? I think it might also be that you aren't reading local.cross inside the memo but inside the function that the memo returns. Though that shouldn't be an issue 🤔 Probably the way you're using Dynamic
Mimikku
MimikkuOP•10mo ago
fair. I had one more case,
const Element = createMemo(
on(
() => props.name,
() => {
sideeffect();

return IconRegistry[props.name];
},
),
);
const Element = createMemo(
on(
() => props.name,
() => {
sideeffect();

return IconRegistry[props.name];
},
),
);
but after thinking about it, i can decouple it into one createEffect(() => sideeffect(props.name)); and one direct prop pass to <Dynamic component={IconRegistry[props.name]}/> Okay i think i get it, thanks unless I have to do the sideefect First and then return the item from the Registry, but I think thats a real valid on()
Want results from more Discord servers?
Add your server