React-React decoration 2.1.0: A collection of decorators for React Components

icon
Latest Release: 2.1.0

This release contains 1 new useful decorator.

@lock

Executes the decorated function as soon as you call it for the first time, and then disables further execution (thanks to @lake-effect in #13)

Source code(tar.gz)
Source code(zip)

react-decoration

Build Status npm version npm downloads Coverage Status Join the chat at https://gitter.im/mbasso/react-decoration

A collection of @decorators for React Components


Attention - In order to use react-decoration you have to use babel 5 or use this plugin for babel 6. Check this page for information.


Installation

You can install react-decoration using npm:

npm install --save react-decoration

If you aren't using npm in your project, you can include reactDecoration using UMD build in the dist folder with <script> tag.

Usage

Once you have installed react-decoration, supposing a CommonJS environment, you can import decorators in this way and immediately use them with no configuration.

import React from 'react';
import { getItems } from './utils';
import { AutoComplete } from './components';
import {
  withStyles,
  debounce,
  killEvent,
  handleRenderError,
} from 'react-decoration';

@withStyles({
  container: {
    width: '100%',
    height: 'auto',
  },
  input: {
    width: 250,
  },
})
@handleRenderError((ex) => <div className="danger">{ex.message}<div>)
class SampleForm extends React.Component {

  state = {
    value: 'Hello!',
    items: [],
  }

  @debounce(500)
  handleChange(e) {
    getItems().then((response) => {
      this.setState({
        value: this.state.value,
        items: response.data.items,
      });
    });

    this.setState({
      value: e.target.value,
      items: this.state.items,
    });
  }

  @killEvent
  handleSubmit() {
    // default prevented
    // propagation stopped

    alert(`AutoComplete value is: ${this.state.value}`);
  }

  render() {
    const { styles } = this.props;
    return (
      <div style={styles.container}>
        <AutoComplete
          value={this.state.value}
          items={this.state.items}
          onChange={this.handleChange}
          style={styles.input}
        />
        <button onClick={this.handleSubmit}>
          Submit
        </button>
      </div>
    );
  }
}

Documentation

Visit docs folder to find the complete list of decorators and their usage.

Change Log

This project adheres to Semantic Versioning. Every upstream release, along with the migration instructions, is documented on the Github Releases page.

Authors

Matteo Basso

Ashley Lake

Copyright and License

Copyright (c) 2016, Matteo Basso.

react-decoration source code is licensed under the MIT License.

Comments

  • Need help to find some decorators
    Need help to find some decorators

    Feb 22, 2017

    General Information

    • [ ] Bug
    • [x] Improvement
    • [ ] Feature
    • [ ] Other

    Description

    Hey guys, I'm looking for new useful decorators to include in this library, do you have any idea?

    help wanted question 
    Reply
  • Event pooling + async decorators
    Event pooling + async decorators

    Jun 28, 2018

    General Information

    • [ ] Bug
    • [ ] Improvement
    • [ ] Feature
    • [x] Other

    Description

    I have a question. According to https://stackoverflow.com/a/28046731/6928824 event pooling may be a problem for the throttle/debounce decorators. In your README example you use the debounce decorator for event handling so I guess it has worked for you so far.

    So wouldn't it be better to call event.persist() before running the decorated function (I haven't found any code doing that)? Maybe your example works because the event is cleaned after a longer time - so debounce(10e4) would not work...I haven't played around it yet.

    Versions

    • react-decoration: 2.0.0
    • Browser: -
    Reply
  • [WIP] Decorator chaining
    [WIP] Decorator chaining

    Aug 28, 2018

    Decorators should be chainable.

    This includes the @autobind decorator which uses a different descriptor type than all other decorators in this lib. Thus, currently something like this cannot be used:

    class {
      a = 42
    
      @debounce(500)
      @autobind
      myMethod() { return this.a }
    }
    

    See #10 for details.

    Reply
  • super() is only allowed in a derived constructor
    super() is only allowed in a derived constructor

    Sep 27, 2018

    General Information

    • [ ] Bug
    • [ ] Improvement
    • [ ] Feature
    • [x] Other

    Description I'm trying to use @component decorator and it shows this error.

    Version: webpack 4.20.2
    Time: 57ms
    Built at: 09/27/2018 2:44:37 PM
         Asset       Size  Chunks             Chunk Names
     bundle.js    1.1 MiB    main  [emitted]  main
    index.html  440 bytes          [emitted]
    Entrypoint main = bundle.js
    [./src/Components/TodoList.js] 2.14 KiB {main} [built] [failed] [1 error]
        + 45 hidden modules
    
    ERROR in ./src/Components/TodoList.js
    Module build failed (from ./node_modules/babel-loader/lib/index.js):
    SyntaxError: /Users/jasinyip/prj/hi/react-todolist/my-app/src/Components/TodoList.js: super() is only allowed in a derived constructor
       4 | @component
       5 | class Counter {
       6 |   constructor () {
    >  7 |     super()
         |     ^
       8 |     this.state = {
       9 |       val: 2
      10 |     }
        at File.buildCodeFrameError (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/core/lib/transformation/file/file.js:261:12)
        at NodePath.buildCodeFrameError (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/path/index.js:157:21)
        at Object.Super (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/plugin-transform-classes/lib/transformClass.js:81:18)
        at NodePath._call (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/path/context.js:53:20)
        at NodePath.call (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/path/context.js:40:17)
        at NodePath.visit (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/path/context.js:88:12)
        at TraversalContext.visitQueue (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/context.js:118:16)
        at TraversalContext.visitSingle (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/context.js:90:19)
        at TraversalContext.visit (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/context.js:146:19)
        at Function.traverse.node (/Users/jasinyip/prj/hi/react-todolist/my-app/node_modules/@babel/traverse/lib/index.js:94:17)
     @ ./src/App.js 21:0-45 47:33-41
     @ ./src/index.js
     @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/index.js
    Child html-webpack-plugin for "index.html":
         1 asset
        Entrypoint undefined = index.html
           4 modules
    ℹ 「wdm」: Failed to compile.
    

    Steps to reproduce

    import { autobind, component } from 'react-decoration'
    
    @component
    class Counter {
      constructor () {
        super()
        this.state = {
          val: 2
        }
      }
    
      render () {
        return (
          <div onClick={this.increment}>
            {this.state.val}
          </div>
        )
      }
    
      @autobind
      increment () {
        this.setState({ val: this.state.val + 1 })
      }
    }
    
    export default Counter
    

    Versions

    {
      "dependencies": {
        "react": "^16.5.2",
        "react-decoration": "^2.0.0",
        "react-dom": "^16.5.2",
        "react-scripts": "1.1.5"
      },
      "devDependencies": {
        "@babel/core": "^7.1.0",
        "@babel/plugin-proposal-decorators": "^7.1.0",
        "@babel/preset-env": "^7.1.0",
        "@babel/preset-react": "^7.0.0",
        "babel-loader": "^8.0.2",
        "css-loader": "^1.0.0",
        "html-webpack-plugin": "^3.2.0",
        "style-loader": "^0.23.0",
        "webpack": "^4.20.2",
        "webpack-cli": "^3.1.1",
        "webpack-dev-server": "^3.1.9"
      }
    }
    
    • react-decoration: 2.0.0
    Reply
  • Bump react-dom from 16.0.0 to 16.11.0
    Bump react-dom from 16.0.0 to 16.11.0

    Nov 1, 2019

    Bumps react-dom from 16.0.0 to 16.11.0.

    Release notes

    Sourced from react-dom's releases.

    16.11.0 (October 22, 2019)

    React DOM

    • Fix mouseenter handlers from firing twice inside nested React containers. @​yuanoook in #16928
    • Remove unstable_createRoot and unstable_createSyncRoot experimental APIs. (These are available in the Experimental channel as createRoot and createSyncRoot.) (@​acdlite in #17088)

    Artifacts

    • react: https://unpkg.com/[email protected]/umd/ • react-art: https://unpkg.com/[email protected]/umd/ • react-dom: https://unpkg.com/[email protected]/umd/ • react-is: https://unpkg.com/[email protected]/umd/ • react-test-renderer: https://unpkg.com/[email protected]/umd/ • scheduler: https://unpkg.com/[email protected]/umd/

    16.10.2 (October 3, 2019)

    React DOM

    • Fix regression in react-native-web by restoring order of arguments in event plugin extractors (@​necolas in #16978)

    Artifacts

    • react: https://unpkg.com/[email protected]/umd/ • react-art: https://unpkg.com/[email protected]/umd/ • react-dom: https://unpkg.com/[email protected]/umd/ • react-is: https://unpkg.com/[email protected]/umd/ • react-test-renderer: https://unpkg.com/[email protected]/umd/ • scheduler: https://unpkg.com/[email protected]/umd/

    16.10.1 (September 28, 2019)

    React DOM

    • Fix regression in Next.js apps by allowing Suspense mismatch during hydration to silently proceed (@​sebmarkbage in #16943)

    16.10.0 (September 27, 2019)

    React DOM

    Scheduler (Experimental)

    • Improve queue performance by switching its internal data structure to a min binary heap. (@​acdlite in #16245)
    • Use postMessage loop with short intervals instead of attempting to align to frame boundaries with requestAnimationFrame. (@​acdlite in #16214)
    ... (truncated)
    Changelog

    Sourced from react-dom's changelog.

    16.11.0 (October 22, 2019)

    React DOM

    • Fix mouseenter handlers from firing twice inside nested React containers. @​yuanoook in #16928
    • Remove unstable_createRoot and unstable_createSyncRoot experimental APIs. (These are available in the Experimental channel as createRoot and createSyncRoot.) (@​acdlite in #17088)

    16.10.2 (October 3, 2019)

    React DOM

    • Fix regression in react-native-web by restoring order of arguments in event plugin extractors (@​necolas in #16978)

    16.10.1 (September 28, 2019)

    React DOM

    • Fix regression in Next.js apps by allowing Suspense mismatch during hydration to silently proceed (@​sebmarkbage in #16943)

    16.10.0 (September 27, 2019)

    React DOM

    Scheduler (Experimental)

    • Improve queue performance by switching its internal data structure to a min binary heap. (@​acdlite in #16245)
    • Use postMessage loop with short intervals instead of attempting to align to frame boundaries with requestAnimationFrame. (@​acdlite in #16214)

    useSubscription

    • Avoid tearing issue when a mutation happens and the previous update is still in progress. (@​bvaughn in #16623)

    16.9.0 (August 8, 2019)

    React

    • Add <React.Profiler> API for gathering performance measurements programmatically. (@​bvaughn in #15172)
    • Remove unstable_ConcurrentMode in favor of unstable_createRoot. (@​acdlite in #15532)

    React DOM

    ... (truncated)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot ignore this [patch|minor|major] version will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    Reply
  • [Feature] Provider a state property decorator.
    [Feature] Provider a state property decorator.

    Mar 25, 2020

    General Information

    • [ ] Bug
    • [ ] Improvement
    • [x] Feature
    • [ ] Other

    Description

    For simply use state properties.

    @component()
    export default class Hello extends Component<{name: string}, any> {
      @state()
      name = this.props.name;
    
      @state()
      age: number = 20;
    
      render() {
        console.log("render hello");
        return (
          <div>
            Hello {this.name}, age: {this.age}
            <br />
            <button onClick={this.handleClick}>Incr age</button>
          </div>
        );
      }
    
      private handleClick = () => {
        this.age++;
      };
    }
    

    Steps to reproduce

    https://codesandbox.io/s/provider-a-state-property-decorator-r8yh3

    Reply
  • Can you provide a simple example for each decorator?
    Can you provide a simple example for each decorator?

    Jan 14, 2017

    Can you provide a simple example for each decorator?

    Reply
  • do not import unnecessary decorators
    do not import unnecessary decorators

    Oct 31, 2016

    General Information

    • [ ] Bug
    • [ x ] Improvement
    • [ ] Feature
    • [ ] Other

    Description

    i tried react-decoration with react-boilerplate, it's great, but the only issue is bundle size :

    before

    Version: webpack 2.1.0-beta.22
    Time: 19226ms
                                        Asset       Size  Chunks             Chunk Names
              3.276f03ea0a17756b8a66.chunk.js     7.8 kB       3  [emitted]
                                    .htaccess    1.53 kB          [emitted]
                                manifest.json  624 bytes          [emitted]
              0.b967f0bb33e8c1f9801c.chunk.js    66.8 kB       0  [emitted]
              1.c6c8c78ee23a90950b3f.chunk.js    79.7 kB       1  [emitted]
              2.3c0fd83ed0be4e272278.chunk.js    25.3 kB       2  [emitted]
                                  favicon.ico    15.1 kB          [emitted]
              4.8526170230b22366d99e.chunk.js    3.43 kB       4  [emitted]
              5.2f3d2e1475dcdf3d02bb.chunk.js  571 bytes       5  [emitted]
                 main.be58e1bd77b283349da5.js     393 kB       6  [emitted]  main
    main.7de2fbe314ffdbfdcc0733fdd993e7a0.css  908 bytes       6  [emitted]  main
                                   index.html  621 bytes          [emitted]
                                        sw.js    13.6 kB          [emitted]
    

    after

    Version: webpack 2.1.0-beta.22
    Time: 20009ms
                                        Asset       Size  Chunks             Chunk Names
              3.276f03ea0a17756b8a66.chunk.js     7.8 kB       3  [emitted]
                                    .htaccess    1.53 kB          [emitted]
                                manifest.json  624 bytes          [emitted]
              0.42c9f3bb7483cb57a46d.chunk.js     112 kB       0  [emitted]
              1.08976c80ec099195e156.chunk.js    66.8 kB       1  [emitted]
              2.3c0fd83ed0be4e272278.chunk.js    25.3 kB       2  [emitted]
                                  favicon.ico    15.1 kB          [emitted]
              4.8526170230b22366d99e.chunk.js    3.43 kB       4  [emitted]
              5.2f3d2e1475dcdf3d02bb.chunk.js  571 bytes       5  [emitted]
                 main.e9d7fd3bddaa80e91f4e.js     393 kB       6  [emitted]  main
    main.7de2fbe314ffdbfdcc0733fdd993e7a0.css  908 bytes       6  [emitted]  main
                                   index.html  621 bytes          [emitted]
                                        sw.js    13.6 kB          [emitted]
    

    the only different is i use

    import { throttle } from 'react-decoration';
    

    and the final build size increased about 32kb

    i think it import all the decorators ?

    Versions

    • react-decoration: latest
    • Browser: all
    Reply
  • Upgrade to react 16
    Upgrade to react 16

    Sep 29, 2017

    Allows the usage of react-decoration with react 16

    Reply
  • add support for debounce && throttle ?
    add support for debounce && throttle ?

    Oct 22, 2016

    General Information

    • [ ] Bug
    • [x] Improvement
    • [ ] Feature
    • [ ] Other

    Description

    debounce and throttle are very common in dev, could it be added?

    enhancement 
    Reply
  • Missing /lib folder - Unable to use the package
    Missing /lib folder - Unable to use the package

    Nov 14, 2016

    General Information

    • [x ] Bug
    • [ ] Improvement
    • [ ] Feature
    • [ ] Other

    Description

    I have installed the package in my project. At first Atom was complaining that it couldn't find the module:

    screen shot 2016-11-14 at 12 33 51

    That's probably because the "main" field in the package.json file is set to "lib/index.js", but there's no lib folder in the project. Looking at the npm scripts I found the build script, that should generate the lib folder, but I'm not sure when that's supposed to happen. Maybe as a postinstall script?

    Steps to reproduce

    Install the package via npm install and import one of the decorators in a project.

    Versions

    • react-decoration: 1.4.0
    • Browser: No browser needed, happens on node level
    bug 
    Reply
  • Added @lock
    Added @lock

    Jun 10, 2019

    • [x] Pull request has tests / docs demo, and is linted.
    • [x] Description explains the issue / use-case resolved, and auto-closes the related issue(s) (https://help.github.com/articles/closing-issues-via-commit-messages/).

    This is an implementation of a decorator slightly different from @debounce or @throttle: it disables the decorated event handler after the first time it is triggered. My team has found it useful for ensuring navigation events only trigger once, since navigation will destroy the decorated component after it completes. There's no issue for this but it's a feature we need.

    The PR also removes trailing whitespace from lines and hard wraps documentation.

    Reply