roact-rodux
roact-rodux copied to clipboard
Documentation Request: Include a complete, annotated implementation example
As someone who struggled to understand this library after reading it from top to bottom, word-for-word, I would've really appreciated a complete, back-to-front example of Roact-Rodux implementation. I wrote this script below to help anyone in the future that wants to poke and prod at a working example :) Please consider putting this in the documentation after peer reviewing my comments for accuracy!
--[[
This is a complete example of Roact-Rodux that will create a
TextButton that will increment its text when its .Activated event is fired!
1) Put Roact, Rodux and RoactRodux in ReplicatedStorage
2) Paste this script in a LocalScript
]]
--Init
local PlayerGui = game.Players.LocalPlayer.PlayerGui
local RS = game:GetService("ReplicatedStorage")
local Roact = require(RS:WaitForChild("Roact"))
local Rodux = require(RS:WaitForChild("Rodux"))
local RoactRodux = require(RS:WaitForChild("RoactRodux"))
--Rodux creates our store:
local function reducer(state, action)
state = state or {
value = 0,
}
if action.type == "increment" then
return {
value = state.value+1
}
end
return state
end
local store = Rodux.Store.new(reducer)
--Roact creates our component:
local function MyComponent(props)
--Roact.createElement(ClassName, {Class Properties}, [{Children}])
return Roact.createElement("ScreenGui", {}, {
Roact.createElement("TextButton", {
Text = props.value,
AnchorPoint = Vector2.new(0.5, 0.5),
Position = UDim2.new(0.5, 0, 0.5, 0),
Size = UDim2.new(0, 500, 0, 200),
ZIndex = 0,
[Roact.Event.Activated] = props.onClick,
})
})
end
--`RoactRodux.connect([mapStateToProps, [mapDispatchToProps]])` returns a function that we can pass our plain Roact component `MyComponent` created above as an argument, returning a new RoactRodux-connected component as our new `MyComponent` variable
MyComponent = RoactRodux.connect(
function(state, props) --`mapStateToProps` accepts our store's state and returns props
return {
value = state.value,
}
end,
function(dispatch) --`mapDispatchToProps` accepts a dispatch function and returns props
print("RoactRodux mapDispatchToProps has run.")
return {
onClick = function()
dispatch({
type = "increment",
})
end,
}
end
)(MyComponent) --Here we are passing in our plain Roact component as an argument to RoactRodux.connect(...)
--`MyComponent` should now return a RoactRodux-connected component, which will update and re-render any time the store is changed.
--Here we will wrap a RoactRodux StoreProvider at the top of our Roact component tree. This will make our store readable to the elements & components below it via
local app = Roact.createElement(RoactRodux.StoreProvider, {
store = store,
}, {
Main = Roact.createElement(MyComponent), --Due to the limitations of Roact, we can only have ONE(1) child under a StoreProvider element, so we have to call MyComponent to get the rest of the children. The Store will be passed to MyComponent as arguments.
})
--Roact will now put our app on the screen
Roact.mount(app, PlayerGui, "My Test App")
Verified working in an isolated environment!
Hi, this looks like a great example! If you're interested, you could make a PR to the docs (we use mkdocs, which should be pretty easy to set up locally) and make a page for this example!
Alternatively, you could add this to an example folder and include a rojo project that sets it up as a place file that folks can build and run with rojo.
If you make it a docs page, you might consider breaking it up into sections with some of your comments as just normal text outside of the snippets, and then including the full example at the end with more simplified comments.
Either way, make sure to wrap your comments, preferably at column 80!
Hi, this looks like a great example! If you're interested, you could make a PR to the docs (we use
mkdocs, which should be pretty easy to set up locally) and make a page for this example!Alternatively, you could add this to an example folder and include a rojo project that sets it up as a place file that folks can build and run with rojo.
If you make it a docs page, you might consider breaking it up into sections with some of your comments as just normal text outside of the snippets, and then including the full example at the end with more simplified comments.
Either way, make sure to wrap your comments, preferably at column 80!
Thanks for the feedback, ZoteTheMighty. I'll take a look at capping comments to column 80. I'll be honest- I've never heard of mkdocs and it looks like a few hours of work that might be pushed back until after I reach a major milestone with my current project. I'll definitely be putting a pin in it though.