2.0.0 • Published 3 months ago

use-service v2.0.0

Weekly downloads
59
License
Apache-2.0
Repository
github
Last release
3 months ago

useService react hook

React hook to handle a shared service accross multiple components.

By service we point an instance of a user-defined object using the new operator.

A service may hold a state. That state will be shared to your components. That means your components will be udpated if the service notify it has been updated.

Getting started

just add use-service addon to your project:

npm i use-service

Then you can follow the example at https://github.com/toutpt/use-service/tree/master/src/App.js

example

API

registerService(idOrFunction, func) -> undefined

you have two options:

// foo.js
function $foo() {}

// app.js
registerService('$foo', $foo)

or

// foo.js
function $foo() {}
$foo.id = '$foo'

// app.js
registerService($foo)

useService(id, options) -> service instance

options.subscribe is set by default to true. In case performance are important you can set it to false if you know your component do not display the data of this service.

How to use with typescript

In the following example we build a service able to fetch with abort API. The state management is done by hand to show a real world example.

export class $bar {
	public static $id = '$bar'
	public isLoading: boolean = true
	public error: Error | null = null
	private controller: AbortController | null = null
	public data: any // up to you

	constructor(private $apply: any) {}

	private reset() {
		this.isLoading = true
		this.error = null
		this.$apply()
	}

	abort() {
		if (this.controller) {
			this.controller.abort()
		}
	}

	fetchMe() {
		this.reset()
		this.controller = new AbortController()
		return fetch('/api/bar', { signal: this.controller.signal })
			.then((data) => {
				this.data = data
			})
			.catch((e) => {
				if (e.name !== 'AbortError') {
					this.error = e
				}
			})
			.finally(() => {
				this.isLoading = false
				this.$apply()
			})
	}
}

then, you can register and use it in your component

import React, {useEffect} from 'react';
import { useService } from 'use-service';
// this is one of the main difference
import { $foo as FooService } from './foo.service.ts';

export function MyBar() {
    const $foo : FooService = useService('$foo');
    useEffect(() => {
        $foo.fetchMe();
        return () => $foo.abort();
    }, []);

    if ($foo.error) {
        return (
            <div className="alert alert-danger">
                <p>Could not load: {$foo.error.message}</p>
                <button className="btn btn-default" onClick={() => $foo.fetchMe()}>re try<button>
            </div>
        );
    }

    if ($foo.isLoading) {
        return "loading ... " // use your loading feedback component
    }

    return (
        <div className="foo">
            // display your $foo.data
        </div>
    );
}
2.0.0

3 months ago

0.3.2

3 years ago

0.3.1

5 years ago

0.3.0

5 years ago

0.3.0-1

5 years ago

0.3.0-0

5 years ago

0.2.0

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago