decorative-react.js is an ES7 micro-framework promoting @ decorator pattern-driven app development using react.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
.babelrc
.gitignore
Gruntfile.js
README.md
index.js
index.js.map
package.json

README.md

decorative-react.js

...is an ES7 micro-framework promoting @decorator pattern-driven app development using react.

Using decorators means to write:

  • less lines
  • less complex
  • better maintainable
  • better readable
  • more loosely coupled code.

It's really "decorative" code you will write using @decorators ;)

Decorators were introduced to Babel.js in spring 2015 by Yehuda Katz. Since then, only a few decorators were implemented (see core-decorators). But the world didn't care much, no matter if they are amazing or not.

When I discovered the es7.decorators I realized the power they could bring to my web apps and I began to implement decorative.js.

decorative.js is currently under development but already used to develop a web app which I will release soon. I rely on this framework and it's toolchain (Babel.js) and it works stable for my use-cases. I can't guarantee that it fully works for you but I think it's worth a try or at least a quick look.

decorative-react.js adds some more decorators, specifically for react development on top of the set of decorators provided by decorative.js.

https://github.com/kyr0/decorative-react

Reading the docs of decorative.js before starting to use decorative-react definitely saves you some headaches :)

React decorators

The decorators described in this section can be understood as additions to the set of decorators already available through decorative.js. Both micro-frameworks in combination can be used as building blocks of a modern web application.

Just install this package like this:

npm install decorative-react --save

for your convenience it brings you the whole decorative lib as a dependency.

@Component()

Transforms the decorated class into a React.Component. Therefore it extends from that base class and applies the code required to let a genuine ES6 class act nicely as a React component.

  import { Component } from 'decorative-react';
  
  @Component()
  class MyButton {
      
  }

Limitation: The @Component() decoration should always be the first on a class (see @InitialState)

@Style(JSS:Object)

Assigns a JSS stylesheet object to a Component. The reference to this object is then available in the JSX template via an additional argument (see @Template).

  import { Component, Style } from 'decorative-react';
  import JSS from './MyButton.jss';
  
  @Style(JSS)
  @Component()
  class MyButton {
      
  }

A JSS stylesheet file like MyButton.jss is a plain, exported JavaScript object:

export default {

    myButton: {
        'margin': '50px',
        'box-shadow': '0px 0px 50px rgba(0,0,0, 0.5)',
        'border-radius': '5px 5px 5px 5px'
    }
};

For more information regarding JSS take a look at the JSS repo:

https://github.com/TODO

@Template(JSX:Function)

Injects a JSX template into the Component and mixes a default render() method into the class prototype.

import { Component, Style } from 'decorative-react';
import JSS from './MyButton.jss';
import JSX from './MyButton.jsx';
  
@Template(JSX)  
@Style(JSS)
@Component()
class MyButton {
      
}

A JSX file like MyButton.jsx then could be implemented externally like this:

import React from 'react';
export default function(state:Object, classes:Object, i18n:Object) {

    return <button disabled={state.isButtonDisabled} className=classes.myButton>{i18n['loginButtonLabel']} {this.props.fooBar}</button>
}

Well, this is a template which is already using all the features of all decorators: state, JSS classes and the translation object. A lot of boilerplate code is unnecessary now. There is no syntax error in this example: You can directly return JSX without any function call wrapping!

Limitation: If the arguments are available depends on which decorators you've applied to the Component class.

@InitialState(state:Object)

Injects the initial state into a Component. This way you won't have to write a method for it.

import { Component, Style } from 'decorative-react';
import JSS from './MyButton.jss';
import JSX from './MyButton.jsx';
  
@Template(JSX)  
@Style(JSS)
@InitialState({
    isButtonDisabled: true
})
@Component()
class MyButton {
      
}

Well, as you can see we now come to a sophisticated button class without writing a single line of boilerplate code!

@EventHandler()

Wraps event handler methods of a component and calls them auto-binded to the components scope and with the event.target as the first argument. Btw. it makes clear which methods are interacting directly with JSX.

import { Component, Style } from 'decorative-react';
import JSS from './MyButton.jss';
import JSX from './MyButton.jsx';
  
@Template(JSX)  
@Style(JSS)
@InitialState({
    isButtonDisabled: false
})
@Component()
class MyButton {
      
    @EventHandler()
    onClick(buttonEl, syntheticEvent) {
      
        this.setState({
            isButtonDisabled: true
        });
    }
}

Roadmap

Although a lot has been implemented, there is still a lot to do and you are very welcome to push :)

Features planned to be introduced in the near future:

  • Please create an issue regarding your own feature requests