Skip to content

Instantly share code, notes, and snippets.

@timarney
Forked from developit/*tracked.md
Created March 30, 2017 02:46
Show Gist options
  • Save timarney/421520006e9a28f34f9789382d8015d4 to your computer and use it in GitHub Desktop.
Save timarney/421520006e9a28f34f9789382d8015d4 to your computer and use it in GitHub Desktop.

tracked npm

@tracked is a decorator for Preact that makes working with state values no different than properties on your component instance.

It's one 300 byte function that creates a getter/setter alias into state/setState() for a given key, with an optional initial value. The "magic" here is simply that it works as a property decorator rather than a function, so it appears to integrate directly into the language.

tracked has no dependencies and works with any component implementation that uses this.state and this.setState().

Installation

It's available on npm as tracked (can you believe it?):

npm install --save tracked

Example

Bask in the glory:

class Example extends Component {
  // initialize state.count with a value:
  @tracked count = 1000;
  
  updateCount = e => {
    // updates state.count via setState()
    this.count = e.target.value;
  };
  
  render() {
    return (
      <input
        value={this.count}  // it's just a value!
        onChange={this.updateCount}
      />
    );
  }
}

Ok but seriously, how does it work?

It's a decorator, but you really don't need to care about that to see how things are working. Here's what's going on:

// this terse syntax:
@tracked a = 1;

// ... produces this:
Object.defineProperty(this, 'a', {
    get: () => this.state.a,
    set: v => this.setState({ a: v })
});

License

MIT probably

dist
node_modules
.DS_Store
export default function tracked(obj, key, desc) {
let setter = {};
function initialize() {
Object.defineProperty(this, key, {
configurable: true,
get: () => this.state[key],
set: v => { setter[key] = v; this.setState(setter); }
});
return this.state[key] = desc.initializer();
}
return {
configurable: true,
set(v) {
initialize.call(this);
this[key] = v;
},
get: initialize
};
}
{
"name": "tracked",
"version": "1.1.1",
"description": "A 300 byte @tracked property decorator for Preact.",
"main": "dist/tracked.umd.js",
"modules": "index.js",
"scripts": {
"build": "rollup -c --environment FORMAT:es && rollup -c"
},
"keywords": [
"preact",
"glimmer",
"tracked",
"state"
],
"files": [
"dist",
"index.js"
],
"author": "Jason Miller <[email protected]> (http://jasonformat.com)",
"license": "ISC",
"devDependencies": {
"rollup": "^0.41.6",
"rollup-plugin-buble": "^0.15.0",
"rollup-plugin-uglify": "^1.0.1"
}
}
import uglify from 'rollup-plugin-uglify';
import buble from 'rollup-plugin-buble';
export default {
exports: 'default',
useStrict: false,
entry: 'index.js',
moduleName: 'tracked',
plugins: [
buble(),
process.env.FORMAT!='es' && uglify()
].filter(Boolean),
targets: process.env.FORMAT=='es' ? [
{ format:'es', dest:'dist/tracked.es.js' }
] : [
{ format:'cjs', dest:'dist/tracked.js' },
{ format:'umd', dest:'dist/tracked.umd.js' }
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment