this is just terrible. You shouldn’t use Roact.update
. It’s bad practice. Instead, there are 2 ways you can do this.
- Roact with Rodux(chad way and proper way)
- Update text binding when hint mounts inside of the didMount function
Lets start with Roact and rodux.
Install the modules you need here: Installation - Roact-Rodux Documentation
First, we need to create a store, create a module script called HintStore.
This will have our store.
Add the following code to there:
local Rodux = require(game.ReplicatedStorage:WaitForChild("Rodux")) -- require rodux
local function reducer(_state, action) -- our reducer
if action.type == "HintUpdate" then -- check if the action type is a hint update
return {
hint = action.hint -- returns the state which will be accessed by our ui
}
end
end
local HintStore = Rodux.Store.new(reducer) --create the store
return HintStore
Next, inside our ui, we can do the following:
local replicatedStorage = game:GetService("ReplicatedStorage")
local modules = replicatedStorage:WaitForChild("Modules")
local Roact = require(modules:WaitForChild("Roact"))
local hint = Roact.Component:extend("Hint")
function hint:init()
self.text, self.updateText = Roact.createBinding("")
self.bgColor, self.changebgColor = Roact.createBinding(Color3.fromRGB(42, 42, 42))
self.textColor, self.changeTextColor = Roact.createBinding(Color3.fromRGB(255, 255, 255))
self.visible, self.changeVisibility = Roact.createBinding(false)
end
function hint:render()
return Roact.createElement("TextLabel",{
Size = UDim2.new(.5,0,0.1,0),
BackgroundColor3 = self.bgColor,
TextScaled = true,
Font = Enum.Font.Arial,
TextColor3 = self.textColor,
Position = UDim2.new(0,300,0,0),
Text = self.props.hint, -- the state from the HintStore are sent into the props
Visible = self.visible,
Name = "hintText",
[Roact.Change.Text] = function(text)
if not text ~= "" then
self.changeVisibility(false)
else
self.changeVisibility(true)
end
end
},{
Roact.createElement("UICorner",{
CornerRadius = UDim.new(0,8)
})
})
end
return hint
After this, we need to connect this to our Rodux store, we can do this using RoactRodux. Do this inside of the script rendering the hint.
local replicatedStorage = game:GetService("ReplicatedStorage")
local modules = replicatedStorage:WaitForChild("Modules")
local Roact = require(modules:WaitForChild("Roact"))
local RoactRodux = require(modules:WaitForChild("RoactRodux"))
local hintComponent = require(script:WaitForChild("hintComponent"))
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local playerGui = localPlayer:WaitForChild("PlayerGui")
local remotes = replicatedStorage:WaitForChild("Remotes")
local changeHintRemote = remotes:WaitForChild("ChangeHint")
local HintStore = require(game.ReplicatedStorage:WaitForChild("HintStore")) -- get store
hintComponent = RoactRodux.connect(function(state, _props)
-- this is what is send to component props
if not state then return end
return {
hint = state.hint
}
end)(hintComponent)
local element = Roact.createElement(RoactRodux.StoreProvider, {
store = HintStore
}, {
hintGui = Roact.createElement("ScreenGui",{
ResetOnSpawn = false,
IgnoreGuiInset = true,
},{
Hint = Roact.createElement(hintComponent)
})
})
Roact.mount(element,playerGui)
Next create another local script called “HintUpdater” with the following code:
local remote = game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("ChangeHint")
local HintStore = require(game.ReplicatedStorage:WaitForChild("HintStore"))
remote.OnClientEvent:Connect(function(hint)
HintStore:dispatch({ -- dispatch data
type = "HintUpdate",
hint = hint
})
end)
Now anytime you fire the remote, it’ll update the text(PS: you may not be able to see the UI since the visibility is set to false in ur component props, but if u go to explorer and check the textlabel’s text it’ll be there. )
If you want to test you can do this in a server script:
local remote = game.ReplicatedStorage:WaitForChild("Remotes"):WaitForChild("ChangeHint")
local i = 0
while true do
i += 1
remote:FireAllClients(string.format("Current i value: %d", i))
task.wait(1)
end
and it’ll update the text.
Method 2, use state. I wouldn’t recommend you do this as you’re trying to change the component externally, which means u should use Rodux. But if you for some reason dont want to use rodux you can do the following. But I recommend you use Rodux, it’ll help you as your project grows.
Update your compoennt to have the following code.
local replicatedStorage = game:GetService("ReplicatedStorage")
local modules = replicatedStorage:WaitForChild("Modules")
local Roact = require(modules:WaitForChild("Roact"))
local remotes = replicatedStorage:WaitForChild("Remotes")
local changeHintRemote = remotes:WaitForChild("ChangeHint")
local hint = Roact.Component:extend("Hint")
function hint:init()
self.text, self.updateText = Roact.createBinding("")
self.bgColor, self.changebgColor = Roact.createBinding(Color3.fromRGB(42, 42, 42))
self.textColor, self.changeTextColor = Roact.createBinding(Color3.fromRGB(255, 255, 255))
self.visible, self.changeVisibility = Roact.createBinding(false)
end
function hint:render()
return Roact.createElement("TextLabel",{
Size = UDim2.new(.5,0,0.1,0),
BackgroundColor3 = self.bgColor,
TextScaled = true,
Font = Enum.Font.Arial,
TextColor3 = self.textColor,
Position = UDim2.new(0,300,0,0),
Text = self.text,
Visible = self.visible,
Name = "hintText",
[Roact.Change.Text] = function(text)
if not text ~= "" then
self.changeVisibility(false)
else
self.changeVisibility(true)
end
end
},Roact.createElement("UICorner",{
CornerRadius = UDim.new(0,8)
}))
end
function hint:didMount()
changeHintRemote.OnClientEvent:Connect(function(hint)
self.updateText(hint)
end)
end
return hint
this has less code and does the same thing, but I REALLY WOULDN’T RECOMMEND THIS. You’re trying to externally change the component, which means you should use Rodux. Using Rodux will benefit you as your project grows.
if this helped you out, please mark it as solution thanks