1.0.3 • Published 2 years ago

react-use-services v1.0.3

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

react-use-services

A react module that allows users to handle shared data between components without using state. This is an attempt to move away from situations where state gets overly complex.

Motivation

State in react is a touchy subject. Through experience we found that state is best used scoped to a single component. Global state adds complexity that has resulted in the creation of many potential solutions. With this simple hook components create singleton services that can be shared amongst components.

Usage Example

This module has been created (for now) to be used with typescript. This module is also best used with the observable pattern.

To use Observables install RXJS. This is not included in the module. npm install rxjs

// services/my-service.ts
import Service from 'react-use-services';
import { BehaviorSubject, Observable } from "rxjs";

export class MyService extends Service {
    private dataItem: BehaviorSubject<number> = new BehaviorSubject(0);

    public getDataItem(): Observable<number> {
        return this.dataItem.asObservable();
    }

    public updateDataItem(value: number) {
        this.dataItem.next(value);
    }
}
// App.tsx
import React, { useEffect, useState } from 'react';
import { MyComponent } from './components/my-component';
import { useService } from 'react-use-services';
import { MyService } from './services/my-service';

export default function App() {
  const service = useService(MyService); // here we request the service
  const [thing, setThing] = useState(0);
  const [showComponent, setShowComponent] = useState(false);


  useEffect(() => {
    // best practice is to put this inside use effect to avoid re-rendering
    service.getDataItem().subscribe(setThing);
    // here we update the value
    service.updateDataItem(1);
  }, [service])

  return (
    <>
      <h1>
        ROOT
      </h1>
      <p>{thing}</p>

      {!showComponent && <button
        onClick={() => setShowComponent(true)}
      >Show Component</button>}
      
      <hr />

      {showComponent && <MyComponent />}
    </>
  );
}
// components/my-component
import React, { ReactElement, useEffect, useState } from 'react';
import { useService } from 'react-use-services';
import { MyService } from '../services/my-service';

export function MyComponent(): ReactElement {
    const service = useService(MyService);
    const [thing, setThing] = useState(0);

    useEffect(() => {
        // best practice is to put this inside use effect to avoid re-rendering
        service.getDataItem().subscribe(setThing);

        // after a delay we will set the value and see this change reflected in both components
        setTimeout(() => {
            service.updateDataItem(2);
        }, 2000);
    }, [service]);

    return (
        <>
            <h2>
                My COMPONENT
            </h2>
            <p>{thing}</p>
            <button
                // on click we will set the value and see this change reflected in both components
                onClick={() => service.updateDataItem(thing + 1)}
            >Click Me.</button>
        </>
    );
}

With the above example you can see how all components sunscribed to changes will update when the value is updated. This way users are able to manage important bits of data in dedicated services and leave state at the component level.

This is a work in progress, maybe one day this could deliver value to someone.

Happy Building ♡