Portals
Portals are a special kind of component provided by Roact that enable components to render objects into a separate, non-Roact Instance.
Info
Eventually, there will be a diagram of Roact portals here. For now, just imagine Valve's hit game,Portal.
To create a portal, use theRoact.Portal
component withcreateElement
:
localfunctionPartInWorkspace(props)returnRoact.createElement(Roact.Portal,{target=Workspace},{SomePart=Roact.createElement("Part",{Anchored=true})})end
When we createPartInWorkspace
, even if it's deep into our Roact tree, aPart
Instance namedSomePart
will be created inWorkspace
.
Warning
Portals should only be created to objects that aren't managed by Roact!
One particularly good use for portals is full-screen modal dialogs. When we render a modal dialog, we want it to take over the entire screen, but we want components deep in the tree to be able to create them!
localPlayerGui=game:GetService("Players").LocalPlayer.PlayerGui-- Our Modal component is a standard component, but with a portal at the top!localfunctionModal(props)returnRoact.createElement(Roact.Portal,{target=PlayerGui},{Modal=Roact.createElement("ScreenGui",{},{Label=Roact.createElement("TextButton",{Size=UDim2.new(1,0,1,0),Text="Click me to close!",[Roact.Event.Activated]=function()props.onClose()end})})})end-- A ModalButton contains a little bit of state to decide whether the dialog-- should be open or not.localModalButton=Roact.Component:extend("ModalButton")functionModalButton:init()self.state={dialogOpen=false}endfunctionModalButton:render()localdialog=nil-- If the dialog isn't open, just avoid rendering it.ifself.state.dialogOpenthendialog=Roact.createElement(Modal,{onClose=function()self:setState({dialogOpen=false})end})endreturnRoact.createElement("TextButton",{Size=UDim2.new(0,400,0,300),Text="Click me to open modal dialog!",[Roact.Event.Activated]=function()self:setState({dialogOpen=true})end},{-- If `dialog` ends up nil, this line does nothing!Dialog=dialog})end