The state of a web application can be managed in different ways including but not limited to; RxJS, React and re-usable custom libraries. It is an amazing JavaScript library for constructing user interfaces that contain an internal state management mechanism which integrates with external modules. RxJS is a powerful JavaScript library that manipulates data streams declaratively. Consequently, when joined with either React or custom libraries it gives one an opportunity to create a reusable and efficient state management system.

Observable is an observation-centered library for reactive programming in RxJS. The magic of Observables happens when dealing with and transforming data streams declaratively. An Observable in RxJS represents a stream of values over any amount of time. They can represent event sources such as user input, HTTP requests or even events themselves.

Below is an example in which we will use RxJS to create an Observable which emits numbers sequentially:import { Observable } from 'rxjs';

import { Observable } from 'rxjs';

// Create an observable that emits a sequence of numbers
const numbers$ = new Observable((observer) => {
  observer.next(1);
  observer.next(2);
  observer.next(3);
  observer.complete();
});

// Subscribe to the observable and log the values
numbers$.subscribe(
  (value) => console.log(value), // onNext
  (error) => console.error(error), // onError
  () => console.log('complete') // onComplete
);

Observable can be created in this example by using the Observable constructor and passing a function to define how observable emits values, then observer object will emit three numbers and complete the sequence.

Next, we use the subscribe method to subscribe to the Observable. It takes three functions as its parameters. The first one is called for each value emitted by the Observable (onNext), and the second one is called in case an error occurs (onError). The third function is called when the Observable completes its emission of items.

Running this code will print 1, 2, and 3 in that order followed by complete on the console because those numbers have been produced. These are emitted into these numbers. In other words, the sequence is completed.

In RxJS, you can create stateful Observables that maintain their own internal state. This can be useful for managing and manipulating complex data streams. Here's an example of creating a stateful Observable that maintains a counter:

import { Observable } from 'rxjs';

// Create a stateful observable that maintains a counter
const counter$ = new Observable((observer) => {
  let count = 0;

  const intervalId = setInterval(() => {
    observer.next(count);
    count++;
  }, 1000);

  // Clean up the interval when the observer is unsubscribed
  return () => clearInterval(intervalId);
});

// Subscribe to the observable and log the counter
const subscription = counter$.subscribe((count) => console.log(count));

// After 5 seconds, unsubscribe from the observable
setTimeout(() => subscription.unsubscribe(), 5000);

In this instance, we create a stateful Observable using the Observable constructor and pass a function that describes how it emits values. We declare a count variable which constitutes our inner state and assign 0 to it.

Afterwards, an interval is set by set Interval which sends current count value to Observer every second, while incrementing the count value.

Finally, when the Observer unsubscribes, a cleanup function is returned that clear the interval.

Therefore, we subscribe to the Observable and in turn log out every counter value emitted.

We then unsubscribe from the Observable after 5 seconds through use of subscription object’s unsubscribe method.

On running this snippet of code, we will see console logging counter value every second for five seconds then unsubscription of subscription and clean up of interval process will take place.

One way to achieve reusable state management is by utilizing RxJS Observables to manage your application state. They are objects that emit values over time and can be used to model data streams in your application. The state of your application may be defined as a stream of values with Observables and operators can be used to manipulate or change data as needed.

For an Observable with React, you might want to create a custom React Hook which would subscribe to an Observable and update the component state whenever new values are emitted. You can reuse this hook in your application so as to keep the state management more consistent and predictable.

RxJS aside, it is possible to apply other custom libraries that extend state management capabilities of your application. For instance, you could develop a library providing reusable React components using Observables for managing state. In this case, throughout the application these components can be used for delivering consistent user interface and way of managing data states.