1.0.7 • Published 2 years ago

@rbxts/rodux-effects v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

✨ rodux-effects

An experimental side-effect library for Rodux. It allows running side effects when a selector updates or an action dispatches.

Rodux-effects is designed to simplify interactions within game state where UI is not applicable, like the server.

🔌 Installation and Setup

You need to first install Rodux and add the rodux-effects package:

npm install @rbxts/rodux-effects

yarn add @rbxts/rodux-effects

pnpm add @rbxts/rodux-effects

If your game's state falls under one Rodux store, you can use bind(store) to load it into rodux-effects.

The effectMiddleware value is optional, but it's required to use side effects with actions.

import Rodux from "@rbxts/rodux";
import { bind, effectMiddleware } from "@rbxts/rodux-effects";
import rootReducer from "reducers";

const store = new Rodux.Store(rootReducer, undefined, [effectMiddleware]);

bind(store);

📚 Usage

See the example for detailed usage.

Running a side effect for a selector update is straightforward:

import { onUpdate } from "@rbxts/rodux-effects";
import { selectCounter } from "reducers/counter";

onUpdate(selectCounter, (counter, prevCounter) => {
	print(`Counter changed to ${counter} (${counter - prevCounter})`);
});

You can also run an effect for a specific action dispatch:

import { onDispatch } from "@rbxts/rodux-effects";
import { RootAction } from "reducers";

onDispatch<RootAction>("CLEAR", () => {
	print("Counter cleared");
});

// The second generic is a shortcut for extracting the type of the action.

onDispatch<RootAction, "INCREMENT">("INCREMENT", (action) => {
	print(`Incremented by ${action.amount}`);
});

More complex interactions with the store are also possible.

import { dispatch, getState, onUpdate } from "@rbxts/rodux-effects";
import { setPlayers, selectPlayers } from "reducers/players";
import { selectRoundStatus } from "reducers/round";

function onRoundStart() {
	const players = game.GetService("Players").GetPlayers();
	
	for (const player of players) {
		task.defer(() => player.LoadCharacter());
	}
	
	dispatch(setPlayers(players));
}

function onRoundEnd() {
	const playersLeft = getState(selectPlayers);
	
	for (const player of playersLeft) {
		print(`Player ${player.name} wins!`);
		
		task.defer(() => player.LoadCharacter());
	}
	
	dispatch(setPlayers([]));
}

onUpdate(selectRoundStatus, (roundStatus) => {
	if (roundStatus === "started") {
		onRoundStart();
	} else if (roundStatus === "ended") {
		onRoundEnd();
	}
});
import { dispatch, getState, waitForUpdate } from "@rbxts/rodux-effects";
import { makeSelectPlayerData } from "reducers/player-data";

function getPlayerData(player: Player) {
	const selectPlayerData = makeSelectPlayerData(player.UserId);
	const playerData = getState(selectPlayerData);
	return playerData ? Promise.resolve(playerData) : waitForUpdate(selectPlayerData);
}
1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

0.1.1

2 years ago

0.1.0

2 years ago