Skip to content

Instantly share code, notes, and snippets.

@dimensi
Last active October 11, 2019 13:34
Show Gist options
  • Save dimensi/8bb566310bb677eb0744fb6ec5184af1 to your computer and use it in GitHub Desktop.
Save dimensi/8bb566310bb677eb0744fb6ec5184af1 to your computer and use it in GitHub Desktop.
portals
import { createEvent, createStore } from 'effector'
import { useLayoutEffect } from 'react'
import { useStoreMap } from 'effector-react'
const portalSetted = createEvent()
const portalRemoved = createEvent()
const $portal = createStore({})
$portal
.on(portalSetted, (state, { destination, children }) => ({
...state,
[destination]: children,
}))
.on(portalRemoved, (state, destination) => {
return Object.fromEntries(Object.entries(state).filter(([key]) => key !== destination))
})
export function Portal({ children, destination }) {
useLayoutEffect(() => {
portalSetted({ children, destination })
return () => {
portalRemoved(destination)
}
}, [children, destination])
return null
}
export function PortalOut({ name }) {
return useStoreMap({
store: $portal,
keys: [name],
fn: (portals, [key]) => portals[key] || null,
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment