Open lloydzhou opened 2 years ago
const useProtal = (() => {
let instance: any = {}
return function() {
// 使用单例模式
if (instance.connect) {
return instance
}
const Portal = () => {
const [items, setItems] = useState<{id: string, portal: React.ReactPortal}[]>([])
instance.connect = useCallback((id: string, portal: React.ReactPortal) => {
setItems([...items, {id, portal}])
}, [items])
instance.disconnect = useCallback((id: string) => {
setItems(items.filter(i => i.id !== id))
}, [items])
return (<div id="protal">{items.map(item => item.portal)}</div>)
}
instance.Portal = Portal
instance.wrap = (Component: any) => ({
mount: async (props: any) => {
const { graph, node, container } = props
// 这里使用graph.view.id做前缀
const id = `${graph.view.id}:${node.view.id}`
instance.connect(id, ReactDOM.createPortal(<Component {...props} />, container))
},
unmount: async (props: any) => {
const { graph, node } = props
const id = `${graph.view.id}:${node.view.id}`
instance.disconnect(id)
}
})
return instance
}
})();
const portal = useProtal()
const { Portal } = portal
const TestComponent = (props: any) => {
const { node } = props
const [num, setNum] = useState(0)
node.on('change:data', () => {
setNum(node.getData().num)
})
const inc = useCallback(() => {
node.setData({ num: num + 1 })
}, [num, node])
return (
<Button size="small" onClick={inc}>
Antd Button {num}
</Button>
)
}
const target3 = graph.addNode({
x: 680,
y: 100,
width: 100,
height: 40,
shape: 'html',
html: portal.wrap(TestComponent),
})