rservices

1.0.16 • Public • Published

ES6 Services for React

Why I did this stuff

Recently I did some stuff with Facebooks' ReactJS. Quite soon I thought "Hey, wouldn't services be awesome" and I started to google. I found a working library, that worked for ES5 only.

Current problems with npm

When installing with NPM you will notice, that there are some error and it is not working. I have to compile the lib to ES5 to work with NPM. But due to some dependency-management, I keep getting Errors. Fork it and help me! Either you install it by downloading the lib via Github or you import the lib from the node module directly:

import {..whatever} from '(../)*node_modules/rservices/RServices'

Installation

npm install --save rservices

Usage

Import the relevant parts of RServices, depending on which you need in your current file.

import {DependencyManager, AbstractService, AbstractDIComponent} from 'path/to/RServices';

Then you can create a Service by extending the AbstractService

import {DependencyManager, AbstractService} from 'path/to/RServices';

class ExampleService extends AbstractService {
  getInitialData() {
    return {
      foo: 1,
      bar: "This value was delivered by the ExampleService."
    }
  }

  incrementFoo() {
    var foo = this.get('foo');
    ++foo;
    this.set('foo', foo);
  }
}
DependencyManager.register(ExampleService);

/**
*
* Another Example Service
*
**/
class Example2Service extends AbstractService {
  getInitialData() {
    return {
      foo: 5,
      bar: "This value was reversed by the ExampleService2 and reversed back by the filter."
    }
  }

  doSomethingWithBar() {
    var bar = this.get('bar');
    bar = reverseString(bar);
    this.set('bar', bar);
  }
}
DependencyManager.register(Example2Service);

The getInitialData method sets the default values of that service. incrementFoo is a custom method. Due to explicity the service has to be registered to the DependencyManager.

Then you write a component and extend the AbstractDIComponent. By adding the getComponentDependencies method, you define which state variable should have the value of a service variable.

Then you also have the possibility to access that Service by calling this.$$services.SERVICE_NAME.

import React from 'react';
import ReactDOM from 'react-dom';
import {AbstractDIComponent} from 'path/to/RServices';

class ExampleComponent extends AbstractDIComponent {
  constructor(props) {
    super(props);

    this.state = {
      bar: 0,
      test: "test still contains its default value.",
      something: ""
    }
  }

  getComponentDependencies() {
    return {
      // state var bar should always have the same value as ExampleService.get('foo')
      bar: [
        'ExampleService', 
        'foo', 
        {
          transformers: [(aNumber) => { return aNumber.toString(); }]
        }
      ],
      test: ['ExampleService', 'bar']
    };
  }

  getPrivateComponentDependencies() {
    return {
      // state var bar should always have the same value as ExampleService.get('foo')
      something: ['Example2Service', 'bar', {transformers: [reverseString]}]
    };
  }

  componentDidMount() {
    // access shared service
    this.$$services.ExampleService.incrementFoo();

    // access private service
    this.$$privateServices.Example2Service.doSomethingWithBar();
  }

  render() {
    var blockStyle = {display: 'block'};

    return (
      <div className="text">
        <span style={blockStyle}>The value of "bar" is: {this.state.bar} ({getType(this.state.bar)})</span>
        <span style={blockStyle}>The value of "test" is: {this.state.test} ({getType(this.state.test)})</span>
        <span style={blockStyle}>The value of "something" is: {this.state.something} ({getType(this.state.something)})</span>
      </div>
    );
  }
}

// DependencyManager.toggleProxyUse();
ReactDOM.render(React.createElement(ExampleComponent), document.querySelector('div'));

Use of proxies

ES6 provides the Proxy Class. If you're up to use React Services only with Browsers, that support proxies (ATM only Firefox), you can enable proxies by calling DependencyManager.toggleProxyUse(); before rendering your components.

That way you can access properties of a service directly:

this.$$services.ExampleService.foo++

instead of

this.$$services.ExampleService.set('foo', this.$$services.ExampleService.get('foo') + 1);

Single instances for components

If you want your components to have a non-shared Service, you can use the getPrivateComponentDependencies Method of the AbstractDIComponent. These services will then be stored in this.$$privateServices.

Services without links to state variables

If you want to use services but want to access methods only or just don't want to have a services variable linked to a component state variable, you can use the following two methods:

getServices() {
  return [
    //'ExampleService'
  ];
}
getPrivateServices() {
  return [];
}

Transformers

When a Servicevalue is updated, you might want to transform it somehow before passing it to the component. E. g. your state variable should always contain a string but the value is delivered as integer, you can specify multiple transformer functions. This is done in the getComponentDependencies/getPrivateComponentDependencies methods:

getComponentDependencies() {
  return {
    // state var bar should always have the same value as ExampleService.get('foo')
    bar: [
      'ExampleService', 
      'foo', 
      {
        transformers: [(aNumber) => { return aNumber.toString(); }]
      }
    ],
    test: ['ExampleService', 'bar']
  };
}

Readme

Keywords

none

Package Sidebar

Install

npm i rservices

Weekly Downloads

1

Version

1.0.16

License

ISC

Last publish

Collaborators

  • mohammer5