pmndrs / tunnel-rat

🐀 Non gratum anus rodentum
MIT License
365 stars 9 forks source link

Tunnel within Tunnel does not arrive at Out #1

Closed dennemark closed 2 years ago

dennemark commented 2 years ago

Found an unwanted side effect, if a tunnel is used within a tunnel. I.e. going from react-dom to react-three-fiber to react-dom

const myComp = ()=>{
   return <tunnel.In>
                 <anotherComp>
                        <child />
                  </anotherComp>
               </tunnel.In>
}
const anotherComp = (children) => {
  return <anotherTunnel.In>
                     {children}
                  </anotherTunnel.In>
}

The child seems to be rendered in the wrong react-renderer and does not arrive at its anotherTunnel.out First render: tunnel.In anotherComp and its child are being rendered. Second render: anotherComp arrives at tunnel.Out, but child is not being rerenderd.

A workaround would be, to use a delay parameter on anotherTunnel.In component and call the state update in useEffect instead of useLayoutEffect. But this can still trigger state update to early.

 useLayoutEffect(() => { if(!delay) { set({ current: children }) }, [children, delay])
 useEffect(() => { if(delay) { set({ current: children }) }, [children, delay])

Not nice, but those seem to be nasty issues with a tunnel-rat.

dennemark commented 2 years ago

Closing this one again. I have actually been using my implementation of tunnels, where I am using ids to have multiple tunnel.in`s. In my useLayoutEffect I was removing the id on each rerender:

useLayoutEffect(()=> { 
   add(id, children);
   return () => {
      remove(id)
   }   
}, [children]) 

I had to use two hooks, so removing would only happen on dismount.

useLayoutEffect(()=> { 
   add(id, children);
}, [children]) 

useLayoutEffect(()=> { 
   return () => {
      remove(id)
   }   
}, []) 

The issue is not related to tunnel-rat since it is only using one tunnel.In and the useLayoutEffect can easily handle it as is.

But since this tunneling concept with zustand is still new, I prefer to share my experience here :)