pmndrs / tunnel-rat

🐀 Non gratum anus rodentum

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alternative tunnel implementation

dennemark opened this issue · comments

Was trying to integrate tunnel-rats into drei Html component, since it avoids creating a react-dom renderer for each element, but instead uses the existing react-dom renderer. (pmndrs/drei#1077)

While searching for issues within the tunnel component, I came up with an even simpler interface, but different dependency @preact/signals-react

I left out the versioning so far. Also nearly got one to work that does not need any external dependency, even tried to shortly write my own state manager with useSyncExternal store 😅 but got a bit convoluted. Anyways, it seems to work the same as the zustand approach.

Only thing that I have to check, is the ordering of arrays, but if I can reproduce it, I will open another issue.

https://codesandbox.io/s/html-annotations-forked-p89h6t?file=/src/HtmlTunnel.tsx

import { ReactNode, useLayoutEffect } from "react"
import { signal } from "@preact/signals-react"

export function tunnel() {
  const sig = signal([])
  return {
    Out: () => {
      return <>{sig.value}</>
    },
    In: ({ children }: { children: ReactNode }) => {
      useLayoutEffect(() => {
        sig.value = [...sig.value, children]
        return () => {
          sig.value = sig.value.filter((x) => x !== children)
        }
      }, [children])
      return <></>
    }
  }
}

Concerning the reordering of array, there is actually really an issue. Since useFrame renders more often than react, the order of elements can change, when an array is used. I don´t have a sandbox setting right now, but I had to implement an object store, instead of arrays for the children.

Am using a uuid for convenience in the In store:
https://codesandbox.io/s/html-annotations-forked-sb1cku?file=/src/Tunnel.tsx