SolidJSS
SolidJSโ€ข3y agoโ€ข
11 replies
alloyed

encapsulating logic that uses refs?

Hi, so I'm porting a react app that does something like so (eliding lots of annoying extra details):
function useMyCustomHook(ref)
{
    useEffect(()=>{
        if(ref.current)
        {
            doSomethingWithRef(ref.current);
            return ()=> {cleanup(ref.current);}
        }
        return ()=> {doNothing();}
    }, [])
}

function MyComponent()
{
    const ref: React.RefObject<T> = ...;
    useMyCustomHook(ref);
    return <elment ref={ref} />
}

There's a problem with the naive translation of this:
function createCustomEffect(refB)
{
    createEffect(()=>{
        doSomethingWithRef(refB);
        onCleanup(()=> {cleanup(refB));
    });
}

function MyComponent()
{
    let refA: T = ...;
    createCustomEffect(refA);
    return <elment ref={refA} />
}


which is that unlike react, which will rerun the hook if ref changes, and normally only changes ref.current to prevent this, solid will run the effect one with the initial value, and completely not notice that the refA changed. because of pass-by-value, refB is a copy of the original binding to the original value, not a reference to the refA binding. what alternate patterns should I be trying instead? some off-the-cuff thoughts:
* put the ref into a signal ala ref={setSignal}
* split out the doSomething() parts of the hook and the createEffect() part of the hook. In this world by convention you aren't actually allowed to encapsulate createEffect() calls, only the contents of them (with any dependency injection you need to pass in signals or w/e)
* something else? bring back ref.current?
Was this page helpful?