Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Roblox/roact/llms.txt

Use this file to discover all available pages before exploring further.

Roact manages Roblox Instance event connections as a first-class part of the rendering process. Rather than calling :Connect and storing RBXScriptConnection objects yourself, you declare event handlers directly inside your element’s props table. Roact connects them when the component mounts and disconnects them automatically when the component unmounts.

Connecting to Instance Events with Roact.Event

To listen to a Roblox event, add a prop whose key is Roact.Event.EVENT_NAME and whose value is the callback function you want called when the event fires.
local button = Roact.createElement("TextButton", {
    Text = "Click me!",
    Size = UDim2.new(0, 400, 0, 300),

    [Roact.Event.MouseButton1Click] = function(rbx)
        print("The button was clicked!")
    end
})
Roact.Event uses Lua’s index metamethod, so Roact.Event.MouseButton1Click evaluates to a special marker value that Roact recognises as an event key. You can use any valid Roblox event name this way — Activated, MouseEnter, TouchTap, and so on.

Callback Signature

Roact always passes the Instance that fired the event as the first argument to your callback. Any additional arguments that Roblox provides for that event follow after.
[Roact.Event.MouseButton1Click] = function(rbx, x, y)
    -- rbx  → the ImageButton Instance
    -- x, y → click position (provided by Roblox for this event)
    print("Clicked at", x, y, "on", rbx.Name)
end

Example: ImageButton Click Handler

local function LikeButton(props)
    return Roact.createElement("ImageButton", {
        Size = UDim2.new(0, 64, 0, 64),
        Image = "rbxassetid://12345678",

        [Roact.Event.MouseButton1Click] = function(rbx)
            print(rbx.Name, "was clicked!")
            if props.onLike then
                props.onLike()
            end
        end
    })
end

Automatic Disconnection

Events declared via Roact.Event are disconnected automatically when the component unmounts. You never need to store connection objects or call :Disconnect manually — Roact handles the entire connection lifecycle for you.

Listening to Property Changes with Roact.Change

Roblox Instances expose GetPropertyChangedSignal, which fires whenever a specific property changes. Roact provides a parallel API for this through Roact.Change. Add a prop whose key is Roact.Change.PROPERTY_NAME and whose value is a callback. The callback receives the Instance as its first argument, just like Roact.Event callbacks.
local frame = Roact.createElement("Frame", {
    [Roact.Change.AbsoluteSize] = function(rbx)
        print("Absolute size changed to", rbx.AbsoluteSize)
    end
})
Roact.Change.AbsoluteSize is equivalent to calling frame:GetPropertyChangedSignal("AbsoluteSize"):Connect(...) manually, but is handled declaratively and automatically cleaned up on unmount.

Example: Tracking a ScrollingFrame’s Position

local function ScrollTracker()
    return Roact.createElement("ScrollingFrame", {
        Size = UDim2.new(1, 0, 1, 0),

        [Roact.Change.CanvasPosition] = function(rbx)
            print("Scrolled to", rbx.CanvasPosition)
        end
    })
end

Updating State from Event Handlers

A common pattern is calling self:setState inside an event handler to update a stateful component when the user interacts with the UI:
local Counter = Roact.Component:extend("Counter")

function Counter:init()
    self:setState({ count = 0 })
end

function Counter:render()
    return Roact.createElement("TextButton", {
        Text = "Count: " .. self.state.count,
        Size = UDim2.new(0, 200, 0, 50),

        [Roact.Event.MouseButton1Click] = function(rbx)
            self:setState(function(state)
                return { count = state.count + 1 }
            end)
        end
    })
end
Roact may trigger event handlers while it is in the middle of updating the UI tree. If your event handler calls self:setState synchronously during this window, Roact will throw an error to prevent the tree from entering an inconsistent state. In the future, Roact may automatically defer event handler evaluation to avoid this situation. In the meantime, avoid patterns that cause events to fire synchronously during reconciliation.

Summary

Roact.Event.EVENT_NAME

Connects to a Roblox Instance event. Callback receives (rbx, ...) where rbx is the Instance and ... are the event’s extra arguments.

Roact.Change.PROPERTY_NAME

Connects to GetPropertyChangedSignal. Callback receives (rbx) — the Instance whose property changed.
Both Roact.Event and Roact.Change connections are established on mount and torn down on unmount automatically. Declare them in your props table exactly like any other property.

Build docs developers (and LLMs) love