Adding components that use context to the DOM after mount

I have a component (ShelfScene) that returns a mapped list of items (Shelf). The ShelfScene component appends a few Shelf components onMount and those render and use context fine with no issues. However when I try to append a new Shelf component after mount the new component is not able to read the context. Any Ideas?
10 Replies
thetarnav
thetarnav10mo ago
Could you share some code? is hard to guess rn
TheOinkinator
TheOinkinator10mo ago
You got it here is the component that wraps context:
import { StackDraggingProvider } from "../../../context/StackDraggingContext";
import { SelectedBinderProvider } from "../../../context/SelectedBinderContext";
import { ActiveStackProvider } from "../../../context/ActiveStackContext";
import ShelfScene from "../shelfScene/ShelfScene";

export default function ShelfContextWrap() {
return (
<StackDraggingProvider dragState={"still"}>
<SelectedBinderProvider selectedBinderState={0}>
<ActiveStackProvider activeStackState={null}>
<ShelfScene />
</ActiveStackProvider>
</SelectedBinderProvider>
</StackDraggingProvider>
);
}
import { StackDraggingProvider } from "../../../context/StackDraggingContext";
import { SelectedBinderProvider } from "../../../context/SelectedBinderContext";
import { ActiveStackProvider } from "../../../context/ActiveStackContext";
import ShelfScene from "../shelfScene/ShelfScene";

export default function ShelfContextWrap() {
return (
<StackDraggingProvider dragState={"still"}>
<SelectedBinderProvider selectedBinderState={0}>
<ActiveStackProvider activeStackState={null}>
<ShelfScene />
</ActiveStackProvider>
</SelectedBinderProvider>
</StackDraggingProvider>
);
}
Here is ShelfScene:
import './shelfSceneStyles.css';
import Shelf from '../shelf/Shelf';
import TestComponent from '../../testComponent/TestComponent';
import { createSignal, onMount, For } from 'solid-js';

export default function ShelfScene() {
const [shelfList, setShelfList] = createSignal<any[]>([]);

onMount(() => {
setShelfList((prevList) => [
...prevList,
<TestComponent />,
<Shelf shelfRef="1" />,
<Shelf shelfRef="2" />,
]);
});

function newShelf() {
setShelfList((prevList) => [...prevList, <TestComponent />]);
}

return (
<div
style={{ 'background-color': 'red' }}
onclick={() => {
newShelf();
}}
>
{shelfList().map((component) => {
return component;
})}
</div>
);
}
import './shelfSceneStyles.css';
import Shelf from '../shelf/Shelf';
import TestComponent from '../../testComponent/TestComponent';
import { createSignal, onMount, For } from 'solid-js';

export default function ShelfScene() {
const [shelfList, setShelfList] = createSignal<any[]>([]);

onMount(() => {
setShelfList((prevList) => [
...prevList,
<TestComponent />,
<Shelf shelfRef="1" />,
<Shelf shelfRef="2" />,
]);
});

function newShelf() {
setShelfList((prevList) => [...prevList, <TestComponent />]);
}

return (
<div
style={{ 'background-color': 'red' }}
onclick={() => {
newShelf();
}}
>
{shelfList().map((component) => {
return component;
})}
</div>
);
}
TheOinkinator
TheOinkinator10mo ago
<TestComponent /> and <Shelf /> are components that use context passed in the context wrap component. When I run newShelf() onclick with a generic div it mounts just fine but when I try to add one of the context using components. (shown above ) they do not mount and I get these errors:
No description
TheOinkinator
TheOinkinator10mo ago
If its relevanant this is a multi page application and the I am using astro to handle the routing
thetarnav
thetarnav10mo ago
newShelf fm gets called in an event listener cb which, where context is not available if you wrap component calls with a thunk, so it gets called lazily in jsx it should work
TheOinkinator
TheOinkinator10mo ago
could you enlighten me on what a thunk is? sorry, relatively new to programming in general and solid. thanks!
thetarnav
thetarnav10mo ago
() =>
TheOinkinator
TheOinkinator10mo ago
so:
function newShelf() {
setShelfList((prevList) => [...prevList, () => {<TestComponent />}]);
}

onclick={() => {
newShelf();
}}
function newShelf() {
setShelfList((prevList) => [...prevList, () => {<TestComponent />}]);
}

onclick={() => {
newShelf();
}}
OK adding a return to the thunk does the trick:
function newShelf() {
setShelfList((prevList) => [...prevList, () => { return <TestComponent />}]);
}

onclick={() => {
newShelf();
}}
function newShelf() {
setShelfList((prevList) => [...prevList, () => { return <TestComponent />}]);
}

onclick={() => {
newShelf();
}}
Thank you much!
thetarnav
thetarnav10mo ago
you should probably look into rendering them with For instead though you’re at risk of rerendering components a lot of you just map over an array and render that
TheOinkinator
TheOinkinator10mo ago
yes I was using for initially I switched to the map during the debugging process. Thanks for the advice!
Want results from more Discord servers?
Add your server
More Posts