Externally affect roact component

--// SERVICES \\--

local TweenService = game:GetService("TweenService")

--// DEPENDENCIES \\--

local Deps = script.Parent.Parent.Dependencies
local Roact = require(Deps.Roact)
local genElements = require(script.Parent.GenElements)

--// MAIN \\--

local Switch = Roact.Component:extend("Switch")

function Switch:init()
	self:setState({
		isOn = self.props.InitialState or false,
		ButtonPosition = self.props.InitialState and UDim2.new(0.5, 0, 0, 0) or UDim2.new(0, 0, 0, 0) 
	})

	self.buttonRef = Roact.createRef() 
end

function Switch:toggle(manualState)
	local newState = not self.state.isOn
	
	if manualState then
		newState = manualState
	end
	
	local newPosition = newState and UDim2.new(0.5, 0, 0, 0) or UDim2.new(0, 0, 0, 0)

	self:setState({
		isOn = newState
	})

	if self.buttonRef.current then
		local tweenInfo = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
		local tween = TweenService:Create(self.buttonRef.current, tweenInfo, {Position = newPosition})
		tween:Play()
	end

	if self.props.ChangedState then
		self.props.ChangedState(newState)
	end
end

function Switch:render()
	local props = self.props
	local state = self.state

	local childrenChildren = {
		genElements["UICorner"](props.InnerCorner or 0.1),
		genElements["UIPadding"](props.innerPadding or 0.1),
	}

	local children = {
		Roact.createElement("ImageButton", {
			[Roact.Ref] = self.buttonRef,
			Size = UDim2.new(0.5, 0, 1, 0),
			Position = state.ButtonPosition, 
			BackgroundTransparency = props.BackgroundTransparency or 0,
			BackgroundColor3 = props.InnerBackgroundColor3 or Color3.fromRGB(230, 230, 230),
			AutoButtonColor = false,
			[Roact.Event.Activated] = function()
				self:toggle()
			end
		}, 
			childrenChildren
		),
	}

	if props.UICorner then
		table.insert(children, genElements["UICorner"](props.UICorner))
	end

	if props.UIPadding then
		table.insert(children, genElements["UIPadding"](props.UIPadding))
	end

	if props.UIStroke then
		table.insert(children, genElements["UIStroke"](props.UIStroke))
	end
	
	if props.Label then
		if props.Label["Size"] == "Automatic" or props.Label["Position"] == "Automatic" then
			table.insert(childrenChildren, genElements["Label"](props.Label, state))
		else
			table.insert(children, genElements["Label"](props.Label, state))
		end
	end

	return Roact.createElement("ImageButton", {
		AnchorPoint =  props.AnchorPoint or Vector2.new(0,0),
		Size = props.Size or UDim2.new(0.068, 0, 0.049, 0),
		Position = props.Position or UDim2.new(0, 0, 0, 0),
		BackgroundColor3 = props.BackgroundColor3 or Color3.fromRGB(20, 20, 20),
		BackgroundTransparency = props.BackgroundTransparency or 0,
		AutoButtonColor = false,
		ClipsDescendants = true,
		[Roact.Event.Activated] = function()
			self:toggle()
		end
	}, children)
end

return Switch

I have this roact component

local Elements = {}

--// SERVICES \\--

local TweenService = game:GetService("TweenService")

--// DEPENDENCIES \\--

local Deps = script.Parent.Dependencies
local Roact = require(Deps.Roact)

--// ELEMENTS \\--

local Switch = require(script.Switch)
local Slider = require(script.Slider)

--// MAIN \\--

function Elements.createSwitch(toParent: GuiObject, switchProps)
	local element = Roact.createElement(Switch, switchProps)
	local handle = Roact.mount(element, toParent)

	return handle
end

function Elements.createSlider(toParent: GuiObject, sliderProps)
	local element = Roact.createElement(Slider, sliderProps)
	local handle = Roact.mount(element, toParent)

	return handle
end

return Elements

then this handler

what i wanna do is use Elements.createSwitch, then be able to make a funciton to sometime in the future give it NEW props, and update the same UI component realtime without unmounting and remounting a replica with the new props.

How can i do this?