Giter Site home page Giter Site logo

rbxts-roact-hooked's Introduction

Roact hooks based on Kampfkarren's hooks & React Hooks

Install

npm install @rbxts/roact-hooked

Usage with hook detection

Version 2.4.0 adds the withHookDetection function to allow hooks in function components without manually using HOCs.

It modifies Roact.createElement to detect hook use and wrap them in withHooks or withHooksPure HOCs.

// MyComponent.tsx
import Roact from "@rbxts/roact";
import { markPureComponent, useEffect, useState } from "@rbxts/roact-hooked";

interface Props {
	name?: string;
}

export default function MyComponent({ name = "David Baszucki" }: Props) {
	const [count, setCount] = useState(0);

	useEffect(() => {
		print("Counter: " + count);
	}, [count]);

	return (
		<textbutton
			Size={new UDim2(1, 0, 1, 0)}
			Text={`${name} pressed ${count} times`}
			Event={{
				Activated: () => setCount((value) => value + 1),
			}}
		/>
	);
}

// Optional: mark the component as a PureComponent
markPureComponent(MyComponent);
// mount.client.ts
import Roact from "@rbxts/roact";
import { withHookDetection } from "@rbxts/roact-hooked";
import { Players } from "@rbxts/services";
import MyComponent from "./MyComponent";

withHookDetection(Roact);

Roact.mount(<MyComponent />, Players.LocalPlayer.WaitForChild("PlayerGui"));

Usage with HOCs

Using the HOCs directly is still possible if you do not want to modify Roact.createElement for hook detection.

import Roact from "@rbxts/roact";
import { withHooks, withHooksPure, useEffect, useState } from "@rbxts/roact-hooked";

interface Props {
	name?: string;
}

function MyComponent({ name = "David Baszucki" }: Props) {
	const [count, setCount] = useState(0);

	useEffect(() => {
		print("Counter: " + count);
	}, [count]);

	return (
		<textbutton
			Size={new UDim2(1, 0, 1, 0)}
			Text={`${name} pressed ${count} times`}
			Event={{
				Activated: () => setCount((value) => value + 1),
			}}
		/>
	);
}

export default withHooks(MyComponent);

// Optional: wrap the FC in a PureComponent instead
export default withHooksPure(MyComponent);

rbxts-roact-hooked's People

Contributors

littensy avatar richie0866 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rbxts-roact-hooked's Issues

Move `stories` outside of `src`

I don't want to keep this directory in src, but I do not know how to move it outside while also including it in roblox-ts for testing in Roblox Studio

Version conflicts result in unusual behavior with Hooks

Functions like resolveCurrentComponent() do not return the same component between different versions of roact-hooked. So, packages that provide useful hooks should use roact-hooked as a peer dependency.

However, should resolveCurrentComponent() be consistent between different instances, anyways? It would keep track of rendering components with _G to make it less error-prone.

Is this change worth it, or would a descriptive error message be enough?

useState set function types are incorrect

const [attributeValue, setAttributeValue] = useState(instance?.GetAttribute(attribute));
useEffect(() => setAttributeValue(instance?.GetAttribute(attribute)), [instance, attribute]);

setAttributeValue() claims it returns void, but actually returns the new state.

In my case, this caused effect.destroy to become true:
https://github.com/littensy/rbxts-roact-hooked/blob/master/src/hooks.lua#L156

Which then caused this check to pass:
https://github.com/littensy/rbxts-roact-hooked/blob/master/src/hooks.lua#L150

Which then throws an error here, because it's doing coroutine.create(true):
https://github.com/littensy/rbxts-roact-hooked/blob/master/src/NoYield.lua#L30

Re-export Roact

Re-export the Roact API with in-built support for hooks. This should help simplify imports and code.

Write tests and refactor code

Code should have unit tests instead of stories for better coverage.

Switch to exposing hooks through a "dispatcher" rather than having that logic be in a file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.