Start typing to search packages!
roact-hooks
By @chipioindustries
Roblox
Mirroredroact-hooks
An implementation of React hooks for Roact. Does not make any modifications to Roact itself.
Example
local Hooks = require(ReplicatedStorage.Hooks)
local Roact = require(ReplicatedStorage.Roact)
-- `props` are our normal passed in properties.
-- `hooks` is passed in by roact-hooks itself.
local function Example(props, hooks)
local count, setCount = hooks.useState(0)
hooks.useEffect(function()
print("the count is", count)
end)
return Roact.createElement(Button, {
onClick = function()
setCount(count + 1)
end,
text = count,
})
end
-- This returns a component that you can call `Roact.createElement` with
Example = Hooks.new(Roact)(Example)
API
Hooks.new
Hooks.new(Roact: Roact) -> (render: (props, hooks) -> RoactComponent | nil, options?: {
name?: string,
defaultProps?: Map<any, any>,
componentType?: string,
validateProps?: (props) -> (false, message: string) | true,
}) -> RoactComponent)
It is required you pass in the Roact you are using, since you can't combine multiple versions of Roact together.
Returns a function that can be used to create a new Roact component with hooks. An optional dictionary can be passed in. The following are the valid keys that can be used, and what they do.
name
Refers to the name used in debugging. If it is not passed, it'll use the function name of what was passed in. For instance, Hooks.new(Roact)(Component) will have the component name "Component".
defaultProps
Defines default values for props to ensure props will have values even if they were not specified by the parent component.
Implemented Hooks
useState
useState<T>(defaultValue: T | (() -> T)) -> (T, update: (value: T | ((prevState: T) -> T)) -> ())
Used to store a stateful value. Returns the current value, and a function that can be used to set the value.
useEffect
useEffect(callback: () -> (() -> void)?, dependencies?: any[])
Used to perform a side-effect with a callback function.
This callback function can return a destructor. When the component unmounts or the dependencies change, this function will be called.
You can also pass in a list of dependencies to useEffect. If passed, then only when those dependencies change will the callback function be re-ran.
useContext
useContext(context: RoactContext<T>) -> T
Returns the value of the context.
useValue
useValue(value: T) -> { value: T }
Similar to useRef in React. Creates a table that you can mutate without re-rendering the component every time. Think of it like a class variable (self.something = 1 vs. self:setState({ something = 1 })).
useCallback
useCallback<F: (...args: any[]) -> any>(callback: F, dependencies: any[]): F
Returns a memoized callback.
useCallback(callback, dependencies) is equivalent to useMemo(function() return callback end, dependencies).
useMemo
useMemo(createValue: () -> T, dependencies: any[]): T
Returns a memoized value.
useMemo will only recalculate the inner value when the dependencies have changed.
The function passed to useMemo runs during rendering, so don't perform any side effects.
If no array is provided, a new value will be computed on every render.
useBinding
useBinding(defaultValue: T) -> RoactBinding<T>, (newValue: T) -> void
These can then be used just like normal bindings in Roact.
useReducer
useReducer(reducer: (state: T, action: A), initialState: T) -> (T, (action: A) -> void)
An alternative to useState that uses a reducer rather than state directly. If you’re familiar with Rodux, you already know how this works.
local initialState = { count = 0 }
local function reducer(state, action)
if action.type == "increment" then
return {
count = state.count + 1,
}
elseif action.type == "decrement" then
return {
count = state.count - 1,
}
else
error("Unknown type: " .. tostring(action.type))
end
end
local function Counter(_props, hooks)
local state, dispatch = hooks.useReducer(reducer, initialState)
return e(Frame, {}, {
Counter = e(Text, {
text = state.count,
}),
Increment = e(Button, {
onClick = function()
dispatch({
type = "increment",
})
end,
}),
Decrement = e(Button, {
onClick = function()
dispatch({
type = "decrement",
})
end,
}),
})
end
Roact
Roact is also provided in the hooks argument. This is useful if custom hooks need direct access to Roact.
-- useCustomHook.lua
local function useCustomHook(hooks)
local Roact = hooks.Roact
end
-- Example.lua
local function Example(props, hooks)
local example = useCustomHook(hooks)
return nil
end
Rules of Hooks
The rules of roact-hooks are the same as those found in React.
Don't call hooks conditionally or in loops.
Call all hooks from the top level of your function. Do not use them in loops or conditions.
Only call hooks from Roact functions.
You can only call hooks from:
- Roact function components
- Custom hooks (a function that begins with the word
use)
Package Details
Install command (Click to copy)
Version
0.6.1
License
MPL-2.0
Usable with conditions
File-level copyleft: if you modify this package's own source files, those modified files must be made available under MPL-2.0. Using it unmodified in a closed-source game is fine.
Automated license review — not legal advice.
