PHP library for state manager

2.3.0 2024-12-25 08:44 UTC

README

cover

Redux - State Manger

<?php

use Redux\Redux;


# Action
$incrementAction = Redux::createAction("INCREMENT");


# Reducer
$counterReducer = Redux::createReducer(0, [
    $incrementAction()["type"] => fn($state, $action) => $state + 1
]);


# Store
$store = Redux::createStore($counterReducer);

echo $store->getState(); # 0

$store->dispatch($incrementAction());

echo $store->getState(); # 1

Installation

Using Composer

composer require arefshojaei/redux

Using Git

git clone https://github.com/ArefShojaei/Redux.git

Guide

Store : State or Container as Global data

# Usage
Redux::createStore($reducer, $middlewares);

Action : An Event to do something

# Usage
Redux::createAction("ACTION");

Reducer : A Function to update state by Action

# Usage
Redux::createReducer($initState, $reducers);

Middleware : A Function to call before Reducer for doing something

# Usage
Redux::createMiddleware($callback);

Apply Middlewares : A Function to get all Middleawres and apply in Store

# Usage
Redux::applyMiddlewares(...$middlewares);

Combine Reducers : Combine all reducers to get an Array with key & value

# Usage
Redux::combineReducers($reducers);

An Example of Counter App

Create Action to fire an Event

  • Increment count
  • Decrement count
  • Reset count
$incrementAction = Redux::createAction("INCREMENT");

$decrementAction = Redux::createAction("DECREMENT");

$resetAction = Redux::createAction("RESET");

Create Reducer to update State

  • Increment count
  • Decrement count
  • Reset count
$initState = 0;

$counterReducer = Redux::createReducer($initState, [
    $incrementAction()["type"] => fn($state, $action) => $state + 1,
    $decrementAction()["type"] => fn($state, $action) => $state - 1,
    $resetAction()["type"] => fn($state, $action) => $state - $state,
]);

Note : when you calling an Action , you should know to get an Array of key & value like this

# Action
$incrementAction = Redux::createAction("INCREMENT");




# call to get this details
$incrementAction()

[
    "type" => "INCREMENT",
    "payload" => null
]

# call to pass argument as payload data to get this details
$incrementAction(["status" => "OK"])

[
    "type" => "INCREMENT",
    "payload" => [
        "status" => "OK"
    ]
]

Create Store by Reducer

$store = Redux::createStore($counterReducer);

Use the Store in project

# Get State from the Store
echo $store->getState(); # 0


# Dispatch Action
$store->dispatch($incrementAction()); # 1
$store->dispatch($incrementAction()); # 2


# Get new State from the Store
echo $store->getState(); # 2

Subscribe the Store as Logger for changing State value

# Subscriber
$unSubscribe = $store->subscribe(function(\Redux\Contracts\Interfaces\Store $store) {
    echo "[Store] updated!" . PHP_EOL;
    echo "[State] value: " . $store->getState();
});



# Get State from the Store
echo $store->getState() . PHP_EOL; # 0


# Dispatch Action
$store->dispatch($incrementAction()); # 1
$store->dispatch($incrementAction()); # 2

$unSubscribe(); # Stop the Subscriber to log

$store->dispatch($incrementAction()); # 3


# Get new State from the Store
echo $store->getState(); # 3

Create Middleware to log the Store & Action

# Logger
$logger = Redux::createMiddleware(function($store, $action, $next) {
    echo "- Logger Middleware -";
    echo "[State] value: " . $store->getState();
    echo "[Action] type: " . $action['type'];

    
    # Call next Middleware or Reducer
    $next($action);
});




# Apply Middlewares
$middlewares = Redux::applyMiddleawres($logger);


# Pass Middlewares as Argument to the Store that has defined yet
$store = Redux::createStore($counterReducer, $middlewares);

Note: Middleware vs Subscriber

Middleware can log Store, Action and call next Middleware of Reducer by the Action!


Subscriber can be like Logger to get changing State value from Store!



View of the Example

<?php

# Put autoload file path
require_once "vendor/autoload.php";


use Redux\Redux;


# Action
$incrementAction = Redux::createAction("INCREMENT");

$decrementAction = Redux::createAction("DECREMENT");

$resetAction = Redux::createAction("RESET");



# Reducer
$initState = 0;

$counterReducer = Redux::createReducer($initState, [
    $incrementAction()["type"] => fn($state, $action) => $state + 1,
    $decrementAction()["type"] => fn($state, $action) => $state - 1,
    $resetAction()["type"] => fn($state, $action) => $state - $state,
]);



# Middleware
$logger = Redux::createMiddleware(function($store, $action, $next) {
    echo "- Logger Middleware -";
    echo "[State] value: " . $store->getState();
    echo "[Action] type: " . $action['type'];

    
    # Call next Middleware or Reducer
    $next($action);
});

$middlewares = Redux::applyMiddlewares($logger);



# Store
$store = Redux::createStore($counterReducer, $middlewares);








# ---------- Usage ----------
# Subscriber
$unSubscribe = $store->subscribe(function(\Redux\Contracts\Interfaces\Store $store) {
    echo "[Store] updated!" . PHP_EOL;
    echo "[State] value: " . $store->getState();
});



# Get State from the Store
echo $store->getState() . PHP_EOL; # 0


# Dispatch Action
$store->dispatch($incrementAction()); # 1
$store->dispatch($incrementAction()); # 2

$unSubscribe(); # Stop the Subscriber to log

$store->dispatch($incrementAction()); # 3


# Get new State from the Store
echo $store->getState(); # 3