S
SolidJS•7mo ago
Mirardes

Dynamic Component is not working

Hi, I try to use Dynamic component without success. I have try to replicate the issue in playground and the bug is still present : Playground : https://playground.solidjs.com/anonymous/83f1450a-6060-4ae1-8361-b6436402949b
import { Dynamic, render } from "solid-js/web";
import { createEffect, createSignal } from "solid-js";

export const StepperLayout = (props) => {
console.log('QWEQWEQWEQE');

return <>STEP LAYOUT {props?.children}</>;
};

export const AppLayout = (props) => {
return <>APP LAYOUT {props?.children}</>;
};


const LayoutHome = (props: { children; currentStep?: string }) => {
const [layout, setLayout] = createSignal(AppLayout);

createEffect(() => {
if (props.currentStep?.startsWith('STEP')) {
setLayout(StepperLayout);
}
});

createEffect(() => {
console.log(layout(), AppLayout);
});

return <Dynamic component={layout()}>{props.children}</Dynamic>;
};

function Counter() {
const [count, setCount] = createSignal(1);
const increment = () => setCount(count() + 1);

return (
<button type="button" onClick={increment}>
{count()}
</button>
);
}

render(() => <><LayoutHome currentStep="STEP">toto</LayoutHome></>, document.getElementById("app")!);
import { Dynamic, render } from "solid-js/web";
import { createEffect, createSignal } from "solid-js";

export const StepperLayout = (props) => {
console.log('QWEQWEQWEQE');

return <>STEP LAYOUT {props?.children}</>;
};

export const AppLayout = (props) => {
return <>APP LAYOUT {props?.children}</>;
};


const LayoutHome = (props: { children; currentStep?: string }) => {
const [layout, setLayout] = createSignal(AppLayout);

createEffect(() => {
if (props.currentStep?.startsWith('STEP')) {
setLayout(StepperLayout);
}
});

createEffect(() => {
console.log(layout(), AppLayout);
});

return <Dynamic component={layout()}>{props.children}</Dynamic>;
};

function Counter() {
const [count, setCount] = createSignal(1);
const increment = () => setCount(count() + 1);

return (
<button type="button" onClick={increment}>
{count()}
</button>
);
}

render(() => <><LayoutHome currentStep="STEP">toto</LayoutHome></>, document.getElementById("app")!);
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
19 Replies
Jasmin
Jasmin•7mo ago
Interesting, if you pass the accessor without calling it, it works but typescript throws an error. <Dynamic component={layout}> Could be a mistake in the type definitions of the Dynamic component ah no this isn't the correct way. I checked the code of <Dynamic> at I'm not sure why this doesn't work thinkies
Mirardes
Mirardes•7mo ago
Yes me too .... Since 25 minutes i'm struggling to understand maybe ping core team ?
Jasmin
Jasmin•7mo ago
Okay you have to wrap the layout components in a function when using them in the signal. This works: https://playground.solidjs.com/anonymous/b5543d36-5b89-4da9-a1c5-5fe368f88333
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Jasmin
Jasmin•7mo ago
can't explain why tho 🙈
Mirardes
Mirardes•7mo ago
WTF doesn't make sense Dynamic don't support Accessible *Accessor so it should not work
Jasmin
Jasmin•7mo ago
it supports getters :)
Mirardes
Mirardes•7mo ago
yes but why with a function return it works and with a value not due to solid-proxy ?
Jasmin
Jasmin•7mo ago
I'm not sure, but would be interested in the explanation @fabiospampinato surely knows whats happening here stare you're probably right. it looks like accessing the signal returns the rendered component
fabiospampinato
fabiospampinato•7mo ago
yeah, if you uncomment the setLayout call both work, though I'm not sure if the one with the signal that returns () => AppLayout actually works
Jasmin
Jasmin•7mo ago
tricky situation you're right, it doesn't work. The initial value has to be createSignal(AppLayout) and you only have to wrap it in a function if you're changing the signal with the setter function https://playground.solidjs.com/anonymous/fc71a309-5ce4-4c2c-9ab5-37a23c8041cf this is the correct solution
Mirardes
Mirardes•7mo ago
Sorry to be stupid but why in these condition it work only with () => ?
Jasmin
Jasmin•7mo ago
because if you're passing a function to the setter, solid thinks you want to do this:
const newCount = setCount((prev) => prev + 1);
const newCount = setCount((prev) => prev + 1);
and runs this function and uses its return value as the new value for the signal and in your case, the return value is the return value of your layout so we have to wrap it in another function
Mirardes
Mirardes•7mo ago
so the issue come from how solid identify Functional Component
lxsmnsyc
lxsmnsyc•7mo ago
no. The issue here is that signal setters can either accept the value or the action. action is a function if you pass a function to the setter, the setter thinks you are passing an "action" so it tries to resolve it.
Mirardes
Mirardes•7mo ago
Okay seems logic
lxsmnsyc
lxsmnsyc•7mo ago
or to simplify
function setSignal(newValue) {
if (typeof newValue === 'function') {
newValue = newValue(currentValue);
}
return updateState(newValue);
}
function setSignal(newValue) {
if (typeof newValue === 'function') {
newValue = newValue(currentValue);
}
return updateState(newValue);
}
Mirardes
Mirardes•7mo ago
I can close the issue thanks !
Jasmin
Jasmin•7mo ago
yes
Want results from more Discord servers?
Add your server
More Posts
Generating Client Only code for static deploymentHey people, I’m trying to build my solid start app for client use only. We’ve got an ordinary, no beMost concise upsert for store?I'm wondering if there was a more efficient way of doing an upsert operation? This is what I'm doingComputations created outside a render will never be disposed.Just wondering whether I can ignore this warning or if its potentially a problem. Basically I have Using Show with createRouteData / useRouteDatCurrently have a project setup with SolidStart, renderStream, and using createRouteData and useRoute1. arguments to useTransition() 2. measuring async updatesquicker one this time :) 1. looking at the official docs for useTransition: ``` import { useTransitiCan't run npm installHowdy y'all, I was trying to use the installer for solid start, and I chose the AuthJS option duringHow do we configure babel proposal decorators with Solid's vite plugin?I've got this Stackblitz: https://stackblitz.com/edit/solidjs-templates-wyjc1i?file=index.html,src%Can't build SolidStart after updating packagesAfter updating packages, I can't build project both locally and on vercel. I can't find anything relhow to trigger the fetcher in createResource if there are multiple signal values?hello, newbie here. In the document, it could be create a Memo as a group of signals as following. WNicest way of having computed properties in a store?I'm trying to model my store in a concise way, I want to have some base properties, and some comput