Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation Request: Include a complete, annotated implementation example #40

Open
SigmaThetaTech opened this issue Sep 6, 2020 · 3 comments

Comments

@SigmaThetaTech
Copy link

SigmaThetaTech commented Sep 6, 2020

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")
@SigmaThetaTech
Copy link
Author

Verified working in an isolated environment!

@ZoteTheMighty
Copy link
Contributor

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!

@SigmaThetaTech
Copy link
Author

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.

@Roblox Roblox deleted a comment from applesm18 Jan 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants