JSFiddle - React, Tailwind, and code Playground

JavaScript

// Function to create a reactive store
function createStore(initialState) {
  // Store the initial state in a private variable
  let state = initialState;

  // Array to hold subscribers (callbacks)
  const subscribers = [];

  // Create a proxy for the state object
  const stateProxy = new Proxy(state, {
    // Trap for setting a property value
    set: function(target, property, value, receiver) {
      // Update the value of the property
      target[property] = value;
      // Trigger callbacks (subscribers) with the updated state
      subscribers.forEach((callback) => callback(stateProxy));
      // Indicate success
      return true;
    },
  });

  // Function to get the current state
  function getState() {
    return stateProxy;
  }

  // Function to subscribe to state changes
  function subscribe(callback) {
    subscribers.push(callback);
    // Return a function to unsubscribe
    return function unsubscribe() {
      const index = subscribers.indexOf(callback);
      if (index !== -1) {
        subscribers.splice(index, 1);
      }
    };
  }

  // Return the getter, setter, and subscribe functions
  return {
    getState,
    subscribe,
  };
}

// Usage example
const store = createStore({ count: 0 });

// Subscribe to state changes
store.subscribe(state => {
  console.log("State changed:", state);
});

// Accessing properties through the getter
console.log(store.getState().count); // Output: 0

// Updating the state through the setter
store.getState().count = 10; // Output: "State changed: { count: 10 }"

// Accessing properties through the getter
console.log(store.getState().count); // Output: 10