{"id":"chipioindustries/roact-hooks","name":"roact-hooks","scope":"chipioindustries","platform":"roblox","description":"An implementation of hooks in Roact","version":"0.6.1","latest":"0.6.1","versions":["0.6.1"],"license":"MPL-2.0","licenseRating":"caution","licenseCaveats":["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."],"licenseVerified":false,"dependencies":{},"integrity":"97f112d049e3593d2e90b202a1f5cd44cda5dc0eff7e613ee5f99c27b9b12553","likes":0,"downloads":0,"install":"forest install chipioindustries/roact-hooks","url":"https://forest.dev/p/roblox/chipioindustries/roact-hooks","files":"https://api.forest.dev/ai/package/roblox/chipioindustries/roact-hooks/files","readme":"# roact-hooks\nAn implementation of [React hooks](https://reactjs.org/docs/hooks-intro.html) for [Roact](https://github.com/Roblox/roact). Does not make any modifications to Roact itself.\n\n## Example\n```lua\nlocal Hooks = require(ReplicatedStorage.Hooks)\nlocal Roact = require(ReplicatedStorage.Roact)\n\n-- `props` are our normal passed in properties.\n-- `hooks` is passed in by roact-hooks itself.\nlocal function Example(props, hooks)\n\tlocal count, setCount = hooks.useState(0)\n\n\thooks.useEffect(function()\n\t\tprint(\"the count is\", count)\n\tend)\n\n\treturn Roact.createElement(Button, {\n\t\tonClick = function()\n\t\t\tsetCount(count + 1)\n\t\tend,\n\n\t\ttext = count,\n\t})\nend\n\n-- This returns a component that you can call `Roact.createElement` with\nExample = Hooks.new(Roact)(Example)\n```\n\n## API\n### Hooks.new\n```\nHooks.new(Roact: Roact) -> (render: (props, hooks) -> RoactComponent | nil, options?: {\n\tname?: string,\n\tdefaultProps?: Map<any, any>,\n\tcomponentType?: string,\n\tvalidateProps?: (props) -> (false, message: string) | true,\n}) -> RoactComponent)\n```\n\nIt is required you pass in the Roact you are using, since you can't combine multiple versions of Roact together.\n\nReturns 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.\n\n#### name\nRefers 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\"`.\n\n#### defaultProps\nDefines default values for props to ensure props will have values even if they were not specified by the parent component.\n\n## Implemented Hooks\n\n### useState\n`useState<T>(defaultValue: T | (() -> T)) -> (T, update: (value: T | ((prevState: T) -> T)) -> ())`\n\nUsed to store a stateful value. Returns the current value, and a function that can be used to set the value.\n\n### useEffect\n`useEffect(callback: () -> (() -> void)?, dependencies?: any[])`\n\nUsed to perform a side-effect with a callback function.\n\nThis callback function can return a destructor. When the component unmounts or the dependencies change, this function will be called.\n\nYou 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.\n\n### useContext\n`useContext(context: RoactContext<T>) -> T`\n\nReturns the value of the [context](https://roblox.github.io/roact/advanced/context/).\n\n### useValue\n`useValue(value: T) -> { value: T }`\n\nSimilar to [useRef in React](https://reactjs.org/docs/hooks-reference.html#useref). 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 })`).\n\n### useCallback\n`useCallback<F: (...args: any[]) -> any>(callback: F, dependencies: any[]): F`\n\nReturns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback.\n\n`useCallback(callback, dependencies)` is equivalent to `useMemo(function() return callback end, dependencies)`.\n\n### useMemo\n`useMemo(createValue: () -> T, dependencies: any[]): T`\n\nReturns a [memoized](https://en.wikipedia.org/wiki/Memoization) value.\n\n`useMemo` will only recalculate the inner value when the dependencies have changed.\n\nThe function passed to `useMemo` runs during rendering, so don't perform any side effects.\n\nIf no array is provided, a new value will be computed on every render.\n\n### useBinding\n`useBinding(defaultValue: T) -> RoactBinding<T>, (newValue: T) -> void`\n\nReturns a [memoized](https://en.wikipedia.org/wiki/Memoization) [binding](https://roblox.github.io/roact/advanced/bindings-and-refs/#bindings).\n\nThese can then be used just like normal bindings in Roact.\n\n### useReducer\n`useReducer(reducer: (state: T, action: A), initialState: T) -> (T, (action: A) -> void)`\n\nAn alternative to `useState` that uses a reducer rather than state directly. If you’re familiar with Rodux, you already know how this works.\n\n```lua\nlocal initialState = { count = 0 }\n\nlocal function reducer(state, action)\n\tif action.type == \"increment\" then\n\t\treturn {\n\t\t\tcount = state.count + 1,\n\t\t}\n\telseif action.type == \"decrement\" then\n\t\treturn {\n\t\t\tcount = state.count - 1,\n\t\t}\n\telse\n\t\terror(\"Unknown type: \" .. tostring(action.type))\n\tend\nend\n\nlocal function Counter(_props, hooks)\n\tlocal state, dispatch = hooks.useReducer(reducer, initialState)\n\n\treturn e(Frame, {}, {\n\t\tCounter = e(Text, {\n\t\t\ttext = state.count,\n\t\t}),\n\n\t\tIncrement = e(Button, {\n\t\t\tonClick = function()\n\t\t\t\tdispatch({\n\t\t\t\t\ttype = \"increment\",\n\t\t\t\t})\n\t\t\tend,\n\t\t}),\n\n\t\tDecrement = e(Button, {\n\t\t\tonClick = function()\n\t\t\t\tdispatch({\n\t\t\t\t\ttype = \"decrement\",\n\t\t\t\t})\n\t\t\tend,\n\t\t}),\n\t})\nend\n```\n\n### Roact\nRoact is also provided in the hooks argument. This is useful if custom hooks need direct access to Roact.\n```lua\n-- useCustomHook.lua\nlocal function useCustomHook(hooks)\n\tlocal Roact = hooks.Roact\nend\n\n-- Example.lua\nlocal function Example(props, hooks)\n\tlocal example = useCustomHook(hooks)\n\treturn nil\nend\n```\n\n## Rules of Hooks\nThe rules of roact-hooks are the same as [those found in React](https://reactjs.org/docs/hooks-rules.html).\n\n### Don't call hooks conditionally or in loops.\nCall all hooks from the top level of your function. Do not use them in loops or conditions.\n\n### Only call hooks from Roact functions.\n\nYou can only call hooks from:\n- Roact function components\n- Custom hooks (a function that begins with the word `use`)\n","readmeTruncated":false}