Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jide
Forked from developit/*tracked.md
Last active March 30, 2017 23:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jide/d09e0ff6521cc17d8c699f110ab013bf to your computer and use it in GitHub Desktop.
Save jide/d09e0ff6521cc17d8c699f110ab013bf to your computer and use it in GitHub Desktop.

tracked (fork) 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(), async
    await this.count = e.target.value;
    console.log(this.state);
  };
  
  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 = {};
obj.state = obj.state === undefined ? {} : obj.state;
function initialize() {
Object.defineProperty(this, key, {
configurable: true,
get: () => this.state[key],
set: v => {
return new Promise(resolve => {
setter[key] = v;
this.setState(setter, resolve);
})
}
});
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 <jason@developit.ca> (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