You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There I use ref to provide a callback in the child component for the parent to be used, like if an event happens and something needs to be activated in the child component. Click in the codepen example on the Toggle Child Message button and it works just fine toggling on and off the Now you see me message. But as soon as you toggle the child component on and off, by pressing the Toggle Child button and forces it to be recreated, because it is in a Show element, the app breaks and causes a minor memory leak keeping one child component alive in memory.
The issue is about when you assign a variable to a child component by passing it down via the ref property. It is nowhere stated explicitly that if you pass anything but a function it essentially rewrites into a function assigning the variable with whatever the child component feeds into it.
Like in the codepen here in main.tsx, when I give it a variable via ref
<ChildElementref={toggleChildMessage}/>
And in the child component I call props.ref to link the function I wanna trigger on the child from the parent component via:
// this is a memory leak when child component is recreated in the parentprops.ref(toggleChildMessage);
So how ref works really is if you give it a function it will execute this function like the docs state. But if you don't use this function variant of ref but give it a different data type than function it is essentially rewritten to be an assignment function to be called by the child component:
letvariable;<SomeComponentref={variable}/>// in the child this arrives asprops.ref=(e)=>{variable=e;}
This is a huge quirk in my opinion and the docs should give more information about this behaviour to make developers aware of this. I've been scratching my head for an hour about it until I finally figured this out. This could have been prevented if the docs would point out quirks like this and give a better understanding of the underlying processes. It is really my fault though because the docs state you can use refs as a function call to be executed but really this is easy to glance over and forget and then you create bugs like these that waste a lot of time. My fault anyways but yeah. Let's make this more clear in the docs.
Code in the codepen:
main.tsx
import{createSignal,Show,}from'solid-js';import{render}from'solid-js/web';importChildElementfrom'./ChildElement';import'./style.scss';constApp=()=>{lettoggleChildMessage;const[showChild,setShowChild]=createSignal(true);functiontoggleChild(){// uncomment this to make it work, as toggleChildMessage is assigned // to be a callback function, it will not be reinitialized by subsequent// child component creations// if (showChild()) {// toggleChildMessage = null; // or set to anything else but a function// }setShowChild(!showChild());}return(<><buttononClick={()=>toggleChild()}>Toggle Child</button><buttononClick={()=>toggleChildMessage()}>Toggle Child Message</button><Showwhen={showChild()}><ChildElementref={toggleChildMessage}/></Show></>);};render(()=><App/>,document.getElementById('app')asHTMLElement);
ChildComponent.tsx
import{createMemo,createSignal}from'solid-js';exportdefault(props)=>{const[opacity,setOpacity]=createSignal(0);conststyle=createMemo(()=>({opacity: opacity(),}));functiontoggleChildMessage(){console.log(style());setOpacity((opacity()+1)%2);console.log(style());}// this is a memory leak when child component is recreated in the parentprops.ref(toggleChildMessage);return(<><div>Child</div><divstyle={style()}>
Now you see me
</div></>);};
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I've come across a "bug" that causes a memory leak with refs because of my lack of knowledge and mishandling it.
Here is a codepen
There I use
ref
to provide a callback in the child component for the parent to be used, like if an event happens and something needs to be activated in the child component. Click in the codepen example on theToggle Child Message
button and it works just fine toggling on and off theNow you see me
message. But as soon as you toggle the child component on and off, by pressing theToggle Child
button and forces it to be recreated, because it is in aShow
element, the app breaks and causes a minor memory leak keeping one child component alive in memory.The issue is about when you assign a variable to a child component by passing it down via the
ref
property. It is nowhere stated explicitly that if you pass anything but a function it essentially rewrites into a function assigning the variable with whatever the child component feeds into it.Like in the codepen here in main.tsx, when I give it a variable via ref
And in the child component I call
props.ref
to link the function I wanna trigger on the child from the parent component via:So how
ref
works really is if you give it a function it will execute this function like the docs state. But if you don't use this function variant ofref
but give it a different data type than function it is essentially rewritten to be an assignment function to be called by the child component:This is a huge quirk in my opinion and the docs should give more information about this behaviour to make developers aware of this. I've been scratching my head for an hour about it until I finally figured this out. This could have been prevented if the docs would point out quirks like this and give a better understanding of the underlying processes. It is really my fault though because the docs state you can use refs as a function call to be executed but really this is easy to glance over and forget and then you create bugs like these that waste a lot of time. My fault anyways but yeah. Let's make this more clear in the docs.
Code in the codepen:
main.tsx
ChildComponent.tsx
Beta Was this translation helpful? Give feedback.
All reactions