State Management

This document provides comprehensive details on the StateManager class, which manages the application's state. It includes functionalities for updating, retrieving, and subscribing to state changes, and ensuring persistent state across sessions.

Purpose

The StateManager class serves as a central point for managing and persisting application state. It offers mechanisms to subscribe to state changes, update and reset the state, and synchronize the state with session storage for persistence across requests.

Constructor

Initializes a new instance of the StateManager class. It loads any saved state from the session upon instantiation and resets the state if the global $isWire variable is not set.

<?php
 use Lib\StateManager;

Methods

getState(string|null $key = null, mixed $initialValue = null): mixed

Retrieves a specific state value or the entire state object if no key is provided. Optionally, the state can be initialized with a provided value if the key does not exist.

$user = StateManager::getState('user', 'guest'); // Retrieve 'user' state or default to 'guest'
 $message = StateManager::getState('message', ['status' => false, 'message' => '']); // Retrieve 'message' state or default array
 $entireState = StateManager::getState(); // Retrieves the entire state

setState(string $key, mixed $value = null): void

Updates the state with the provided key-value pair and saves the updated state to the session. It also notifies listeners of the state change, making it available for subscription. The variable with the new value is set using the provided key and the $GLOBALS[$key] = $value;

StateManager::setState('user', 'admin'); // Update 'user' state to 'admin'
 StateManager::setState('message', ['status' => true, 'message' => 'Success']); // Update 'message' state to array

subscribe(callable $listener): callable

Subscribes a listener function to state changes. The listener is called immediately with the current state and upon each state update. Returns a function to unsubscribe the listener.

$unsubscribe = StateManager::subscribe(function($state) {
    echo "State updated: " . print_r($state, true);
});

// To unsubscribe:
$unsubscribe();

resetState(): void

resetState(string $key = null): void

Resets the application state to an empty array and notifies listeners.

StateManager::resetState(); // Resets the entire state
StateManager::resetState('key'); // Resets the 'key' state only to null

Internal Methods

These methods are primarily used within the class for managing state resolution and persistence.

saveState(): void

Saves the current state to session storage.

loadState(): void

Loads the state from session storage, if available.

notifyListeners(): void

Notifies all subscribed listeners of state changes.

Example Usage

Subscribing and Updating State

<?php

  use Lib\StateManager;
  
  $count = StateManager::getState('count', 0);
  
  function incrementCount()
  {
      global $state, $count;
      StateManager::setState('count', ++$count);
  }
  
  function decrementCount()
  {
      global $state, $count;
      StateManager::setState('count', --$count);
  }
  
  function resetCount()
  {
      global $state;
      StateManager::setState('count', 0);
  }
  
  ?>
  
  <div class="w-screen h-screen grid place-items-center">
      <div class="flex flex-col gap-2">
          <span class="text-blue-500"><?= $count ?></span>
          <div class="flex gap-2">
              <button class="p-2 bg-blue-500 text-white rounded" onclick="incrementCount">Increment</button>
              <button class="p-2 bg-red-500 text-white rounded" onclick="decrementCount">Decrement</button>
              <button class="p-2 bg-gray-500 text-white rounded" onclick="resetCount">Reset</button>
          </div>
      </div>
  </div>

Good to Know

When using the StateManager class, it is important to note that the getState and setState methods provide controlled access and modification to the application state. This prevents direct modification of the state, ensuring a consistent and predictable state across your application.