Variable initialized in `onMount` becomes `undefined`

let positionMenu: () => void;

onMount(() => {
positionMenu = getPositionMenuFun({ inputElement, styles });
console.log('positionMenu', positionMenu); // always outputs the function
});

createEffect(() => {
// ...
positionMenu(); // error: in one scenario `positionMenu` is undefined
});
let positionMenu: () => void;

onMount(() => {
positionMenu = getPositionMenuFun({ inputElement, styles });
console.log('positionMenu', positionMenu); // always outputs the function
});

createEffect(() => {
// ...
positionMenu(); // error: in one scenario `positionMenu` is undefined
});
I initialize a variable returning a function in the onMount callback, then call it in some effect. In one scenario positionMenu will be undefined. It is nowhere else in the code (only these occurrences of "positionMenu" as shown above). I noticed it's due to a clean up but I do not understand how the variable loses its value.
6 Replies
apollo79
apollo792y ago
Can you give a reproduction? In the code above, it seems to work so something is probably missing
thetarnav
thetarnav2y ago
How do you know if the effects run from top to bottom?
Martnart
Martnart2y ago
Might be too obvious (I guess you have checked that off already) but effects also run before mounting. so it's initially undefined.
thetarnav
thetarnav2y ago
GitHub
solid/packages/solid/src/reactive/signal.ts at f79ba4d9087d74ef7e55...
A declarative, efficient, and flexible JavaScript library for building user interfaces. - solidjs/solid
Martnart
Martnart2y ago
I meant that an effect returned from createEffect will execute before onMount Edit: Need to add that I am talking about an SSR context. Might well be not relevant for this particular use-case.
thetarnav
thetarnav2y ago
probably the best way to ensure that the effect will have the variable available is to nest the effect insie onMount:
onMount(() => {
const positionMenu = getPositionMenuFun({ inputElement, styles });

createEffect(() => {
positionMenu();
});
});
onMount(() => {
const positionMenu = getPositionMenuFun({ inputElement, styles });

createEffect(() => {
positionMenu();
});
});

Did you find this page helpful?