(Typescript) Component not allowing children in Roact

I am using roblox-ts to write my code in TypeScript and am also using Roact. I am using .tsx files to write my roact code. I am new to both TS and roact

My problem is that my custom component (a frame which is invisible) will not accept any children.

I have tried looking at the compiled code too, but it seems fine to me. I am new to Roact so it is quite possible I am just using them wrong.

Layout.tsx:

import Roact from "@rbxts/roact";

import EmptyFrame from "../global/EmptyFrame";
import CustomButton from "./Components/CustomButton";
import CustomLabel from "./Components/CustomLabel";

function createLayout(texts: Map<string, Callback>, title: string, bottom: string) {
    return (
        <screengui ResetOnSpawn={ false }>
            <EmptyFrame Size={ new UDim2(0.3, 0, 0.8, 0) } Position={ new UDim2(0.05, 0, 0.1, 0) } Key="Debug1">
                <CustomLabel Font={ Enum.Font.SourceSans } Size={ new UDim2(1, 0, 0.25, 0) } Text={ title } TextSize={ 110 }/>
                <EmptyFrame Key="Debug2">
                    <uilistlayout/>
                    {(() => {
                        let elements: Array<Roact.Element> = new Array<Roact.Element>();

                        texts.forEach((call, text) => {
                            elements.push(<CustomButton Font={ Enum.Font.SourceSansLight } OnClick={ call } Size={ new UDim2(1, 0, 0.2, 0) }
                            Text={ text } TextSize={ 72 }/>)
                        })

                        return elements
                    })()}
                </EmptyFrame>
            </EmptyFrame>
        </screengui>
    )
}

// Create menu
export default createLayout;


layout.lua (compiled):

-- Compiled with roblox-ts v1.1.0
local TS = require(game:GetService("ReplicatedStorage"):WaitForChild("rbxts_include"):WaitForChild("RuntimeLib"))
local Roact = TS.import(script, TS.getModule(script, "roact").src)
local EmptyFrame = TS.import(script, script.Parent.Parent, "global", "EmptyFrame").default
local CustomButton = TS.import(script, script.Parent, "Components", "CustomButton").default
local CustomLabel = TS.import(script, script.Parent, "Components", "CustomLabel").default
local function createLayout(texts, title, bottom)
	local _0 = {
		ResetOnSpawn = false,
	}
	local _1 = {}
	local _2 = #_1
	local _3 = {
		Size = UDim2.new(0.3, 0, 0.8, 0),
		Position = UDim2.new(0.05, 0, 0.1, 0),
	}
	local _4 = {
		Roact.createElement(CustomLabel, {
			Font = Enum.Font.SourceSans,
			Size = UDim2.new(1, 0, 0.25, 0),
			Text = title,
			TextSize = 110,
		}),
	}
	local _5 = #_4
	local _6 = {
		Roact.createElement("UIListLayout"),
	}
	local _7 = #_6
	for _8, _9 in ipairs((function()
		local elements = {}
		local _10 = texts
		local _11 = function(call, text)
			local _12 = elements
			local _13 = Roact.createElement(CustomButton, {
				Font = Enum.Font.SourceSansLight,
				OnClick = call,
				Size = UDim2.new(1, 0, 0.2, 0),
				Text = text,
				TextSize = 72,
			})
			-- ▼ Array.push ▼
			_12[#_12 + 1] = _13
			-- ▲ Array.push ▲
		end
		-- ▼ ReadonlyMap.forEach ▼
		for _12, _13 in pairs(_10) do
			_11(_13, _12, _10)
		end
		-- ▲ ReadonlyMap.forEach ▲
		return elements
	end)()) do
		_6[_7 + _8] = _9
	end
	_4.Debug2 = Roact.createElement(EmptyFrame, {}, _6)
	_1.Debug1 = Roact.createElement(EmptyFrame, _3, _4)
	return Roact.createElement("ScreenGui", _0, _1)
end
-- Create menu
local default = createLayout
return {
	default = default,
}

The first invisible frame appears in the explorer, but none of its children do.
image

Removing the invisible frames fixes the problem, but I would rather learn to properly use components as I quite regularly use them.

EmptyFrame.tsx:

// Empty frame for easy parenting

import Roact from "@rbxts/roact";


interface IProps {
    Size?: UDim2 | undefined
    Position?: UDim2 | undefined
    AnchorPoint?: Vector2 | undefined
}


class EmptyFrame extends Roact.Component<IProps> {
    render() {
        return (
            <frame
                AnchorPoint={ this.props.AnchorPoint }
                Size={ this.props.Size || new UDim2(1, 0, 1, 0) }
                Position={ this.props.Position }
                Transparency={ 1 }
                BorderSizePixel={ 0 }
            />
        )
    }
}

export default EmptyFrame;

EmptyFrame.lua:

-- Compiled with roblox-ts v1.1.0
local TS = require(game:GetService("ReplicatedStorage"):WaitForChild("rbxts_include"):WaitForChild("RuntimeLib"))
-- Empty frame for easy parenting
local Roact = TS.import(script, TS.getModule(script, "roact").src)
local EmptyFrame
do
	EmptyFrame = Roact.Component:extend("EmptyFrame")
	function EmptyFrame:init()
	end
	function EmptyFrame:render()
		return Roact.createElement("Frame", {
			AnchorPoint = self.props.AnchorPoint,
			Size = self.props.Size or UDim2.new(1, 0, 1, 0),
			Position = self.props.Position,
			Transparency = 1,
			BorderSizePixel = 0,
		})
	end
end
local default = EmptyFrame
return {
	default = default,
}

EmtyFrame has to render children prop also.

How would I go about rendering the children?

In your case:

  class EmptyFrame extends Roact.Component<IProps> {
        render() {
            return (
                <frame
                    AnchorPoint={ this.props.AnchorPoint }
                    Size={ this.props.Size || new UDim2(1, 0, 1, 0) }
                    Position={ this.props.Position }
                    Transparency={ 1 }
                    BorderSizePixel={ 0 }
                >{this.props[Roact.Children]}</frame>
            )
        }
    }

or

 class EmptyFrame extends Roact.Component<IProps> {
        render() {
            return (
                <frame
                    AnchorPoint={ this.props.AnchorPoint }
                    Size={ this.props.Size || new UDim2(1, 0, 1, 0) }
                    Position={ this.props.Position }
                    Transparency={ 1 }
                    BorderSizePixel={ 0 }
                    {...{ [Roact.Children]: children }}
                />
            )
        }
    }

Tip: Search for roblox-ts and roact code examples from Github also:
https://github.com/search?l=TSX&q=Roact.Children&type=Code

1 Like