How to mount a component using vanilla Javascript? #1755
-
...while keeping reactivity, of course. (See this discussion for why I want to use vanilla Javascript - basically trying to support plugins written in plain Javascript.) I've tried a few ways, none of which have worked. Setup:const Comp: VoidComponent<{
i: number // some reactive prop
child: VoidComponent<{ i: number }> // some Solid component passed to Javascript that I'm trying to mount
}> = (props) => {
const container = document.createElement("div")
// insert attempted code from below here
return container // this Node is mounted in a solid-app here: https://github.com/AlexErrant/solid-plugin/blob/56729963cc6b3dacc760e123a43e30d5ad46d55e/my-solid-project/src/App.tsx#LL35C16-L35C36
}
export default Comp I don't mind importing Solid's
|
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 13 replies
-
You need to use createComponent(Dynamic, { ... }); |
Beta Was this translation helpful? Give feedback.
-
Why are you avoiding |
Beta Was this translation helpful? Give feedback.
-
Your intent is still not clear to me but here is an example that uses plain javascript both on the root and the leaf. import {
Component,
JSXElement,
createComponent,
createEffect,
createMemo,
createRoot,
createSignal,
onCleanup,
} from 'solid-js';
import { render } from 'solid-js/web';
const Comp: Component<{ count: number }> = (props) => {
let div = document.createElement('div');
createEffect(() => {
div.innerHTML = `Count: ` + props.count;
});
return div;
};
const App = () => {
let dispose: () => void;
const [count, setCount] = createSignal(0);
setInterval(() => setCount((p) => p + 1), 1000);
onCleanup(() => {
dispose && dispose();
});
const el = createRoot((disposer) => {
dispose = disposer;
return createMemo(() =>
createComponent(Comp, {
get count() {
return count();
},
}),
);
}) as unknown as JSXElement;
return <div>{el}</div>;
};
render(App, document.body); |
Beta Was this translation helpful? Give feedback.
-
You know Comp is an actual component and it is reactive. I use imperative API because you were using it almost in all your examples. import {
Component,
JSXElement,
createComponent,
createEffect,
createMemo,
createRoot,
createSignal,
onCleanup,
} from 'solid-js';
import { render } from 'solid-js/web';
const Comp: Component<{ count: number }> = (props) => {
return (
<div>
<div>Count: {props.count}</div>
</div>
);
};
const App = () => {
let dispose: () => void;
const [count, setCount] = createSignal(0);
setInterval(() => setCount((p) => p + 1), 1000);
onCleanup(() => {
dispose && dispose();
});
const el = createRoot((disposer) => {
dispose = disposer;
return createComponent(Comp, {
get count() {
return count();
},
});
});
return <div>{el}</div>;
};
render(App, document.body);
I don't get this, please refactor the code in way to achieve your purpose, we can fix the errors and work towards your goal. Do you want to render props.children reactively? import {
Component,
createComponent,
createRoot,
createSignal,
onCleanup
} from 'solid-js';
import { render } from 'solid-js/web';
const Comp: Component<{ children: number }> = (props) => {
return () => props.children;
};
const App = () => {
let dispose: () => void;
const [count, setCount] = createSignal(0);
setInterval(() => setCount((p) => p + 1), 1000);
onCleanup(() => {
dispose && dispose();
});
const el = createRoot((disposer) => {
dispose = disposer;
return createComponent(Comp, {
get children() {
return count();
},
});
});
return <div>{el}</div>;
};
render(App, document.body); |
Beta Was this translation helpful? Give feedback.
-
Okay, I think I figured it out, please no one try to grok my shitty technical writing. I'll post my solution in a bit, gotta step away to emotionally recover from my stupidity. |
Beta Was this translation helpful? Give feedback.
You need to use
createComponent from "solid-js"
to retain reactivity, e.g.: