{"id":19298812,"url":"https://github.com/studiointeract/tracker-component","last_synced_at":"2025-08-13T20:12:43.353Z","repository":{"id":57378708,"uuid":"54797649","full_name":"studiointeract/tracker-component","owner":"studiointeract","description":"Easy reactive React Components with Meteor and Tracker","archived":false,"fork":false,"pushed_at":"2016-07-18T12:10:07.000Z","size":128,"stargazers_count":37,"open_issues_count":8,"forks_count":4,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-29T11:58:30.684Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/studiointeract.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-26T20:14:45.000Z","updated_at":"2022-10-13T00:14:19.000Z","dependencies_parsed_at":"2022-09-02T21:20:34.468Z","dependency_job_id":null,"html_url":"https://github.com/studiointeract/tracker-component","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/studiointeract/tracker-component","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiointeract%2Ftracker-component","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiointeract%2Ftracker-component/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiointeract%2Ftracker-component/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiointeract%2Ftracker-component/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/studiointeract","download_url":"https://codeload.github.com/studiointeract/tracker-component/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/studiointeract%2Ftracker-component/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270305658,"owners_count":24562087,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-13T02:00:09.904Z","response_time":66,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T23:09:12.938Z","updated_at":"2025-08-13T20:12:43.300Z","avatar_url":"https://github.com/studiointeract.png","language":"JavaScript","readme":"# Tracker.Component\n\nCurrent version 1.3.21\n\n## Features\n\n1. **[Easy to use](#using-trackercomponent)**, manages Tracker for you using autorun, and your subscriptions using the subscribe method, you don't have to manually setup the reactivity bindings or start/stop subscriptions, we promise!\n3. **[Subscriptions](#subscriptions)** are managed through the built in `this.subscribe` and ensures your subscription are correctly stopped when your component unmounts.\n4. **[Composition](#composition) and [Class Inheritance](#class-inheritance)** is easy to achieve, and the preferred methods rather than using Mixins, [read more about Mixin](#mixin).\n5. **[Lightweight](lib/index.jsx)** implementation, have a look in [`index.jsx`](lib/index.jsx), there's no magic going on, only **48 lines of code**.\n6. **[Server Side Rendering](#server-side-rendering)** supported (with data managed trough FlowRouter SSR).\n\n**Tracker.Component** is an improvement to what other methods offer ([see comparison](#comparison)) for React. Using Tracker.Component you are no longer required to \"freeze\" all your reactivity in a single method or composition. You set the state from the reactive data sources (e.g: `collection.find().fetch()` or `Session.get('foo')` in `this.autorun`, which is also reactive to changes in `this.props` or `this.state`. Have fun!\n\n## Installation\n\n`npm i --save tracker-component`\n\n# Using Tracker.Component\n\n\u003e [Go to using with Meteor 1.2](#using-trackercomponent-meteor-12)\n\n`meteor create myapp --release METEOR@1.3`\n\nIn this example we render a couple cars from MongoDB.\n\n\u003e You'll probably recognize the autorun and subscribe from Blaze's Tracker implementation. That's the core idea, simplicity.\n\n`npm i --save react react-dom`\n\n```javascript\n// main.jsx\n\nimport React from 'react';\nimport Tracker from 'tracker-component';\n\nModels = new Mongo.Collection('models');\nif (Meteor.isServer) {\n  Meteor.publish('cars', () =\u003e Models.find());\n}\n\nclass Models extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.subscribe('cars');\n    this.autorun(() =\u003e {\n      this.setState({\n        cars: Models.find().fetch()\n      });\n    });\n  }\n}\n\nconst Cars = ({ cars = [] }) =\u003e (\n  \u003cul className=\"cars\"\u003e\n    {cars.map(car =\u003e\n      \u003cli className=\"car\"\u003e{car.brand} {car.model}\u003c/li\u003e\n    )}\n  \u003c/ul\u003e\n);\n\nif (Meteor.isClient) {\n  Meteor.startup(() =\u003e {\n    ReactDOM.render(\u003cModels\u003e\u003cCars /\u003e\u003c/Models\u003e, document.body);\n  });\n}\n\n```\n\n## Fill with data from the server.\n\n\u003e Try adding new car models while running meteor, you'll notice it is fully reactive throughout the whole stack.\n\n```javascript\n\n// Bootstrap database with some cars.\nMeteor.startup(function() {\n  let models = {\n    \"Volvo\": ['XC90', 'V90', 'V70'],\n    \"Tesla\": ['Model S', 'Model X', 'Model 3', 'Roadster'],\n    \"DeLorean\": [\"DMC-12\"]\n  };\n\n  Object.keys(models).forEach(brand =\u003e {\n    models[brand].forEach(model =\u003e {\n      car = { brand: brand, model: model };\n      Models.upsert(car, car);\n    });\n  });\n});\n\nMeteor.publish('brand', (brand) =\u003e {\n  // Simulate network latency to show the loader.\n  // Meteor._sleepForMs(2000);\n  if (brand) {\n    return Models.find({ brand: brand });\n  }\n  return Models.find();\n});\n\n```\n\n### Result on the client:\n\n```html\n\n\u003cbody\u003e\n  \u003cul class=\"cars\"\u003e\n    \u003cli\u003eVolvo XC90\u003c/li\u003e\n    \u003cli\u003eVolvo V90\u003c/li\u003e\n    \u003cli\u003eVolvo V70\u003c/li\u003e\n    \u003cli\u003eTesla Model S\u003c/li\u003e\n    \u003cli\u003eTesla Model X\u003c/li\u003e\n    \u003cli\u003eTesla Model 3\u003c/li\u003e\n    \u003cli\u003eTesla Roadster\u003c/li\u003e\n    \u003cli\u003eDeLorean DMC-12\u003c/li\u003e\n  \u003c/ul\u003e\n\u003cbody\u003e\n\n```\n\n## Full example: What about adding a loading gif?\n\n[http://github.com/studiointeract/tracker-component-example](http://github.com/studiointeract/tracker-component-example)\n\nWe got you're back on this one too! And have a look below, we've also added a select button to switch between selected car brand.\n\nJust add `this.subscriptionsReady()` to your autorun like below and you will get a reactive boolean to use for a ready flag.\n\nNotice! We advice in using \"ready\" flag rather \"loading\" due to that the data will default be ready when rendered on the server. The reason is basically to avoid having React complaining about different markup on server and client, which would happen when using the loading pattern.\n\n```javascript\n// main.jsx\n\nModels = new Mongo.Collection('models');\n\nBrands = class Cars extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      brand: this.props.brand\n    };\n    this.autorun(() =\u003e {\n      this.subscribe( 'brand', this.state.brand );\n    });\n    this.autorun(() =\u003e {\n      this.setState({\n        ready: this.subscriptionsReady(),\n        cars: Models.find({ brand: this.state.brand }).fetch()\n      });\n    });\n  }\n\n  handleChange() {\n    this.setState({brand: this.refs.brand.value});\n  }\n\n  render() {\n    let {cars = []} = this.state;\n    let selectBrand = this.handleChange.bind(this);\n    let brands = [\"Volvo\", \"Tesla\", \"DeLorean\"];\n\n    return (\n      \u003cdiv\u003e\n        \u003cselect ref=\"brand\" onChange={selectBrand} defaultValue={this.state.selected}\u003e\n          {brands.map((brand, i) =\u003e\n            \u003coption value={brand} key={i}\u003e{brand}\u003c/option\u003e\n          )}\n          {super.render()}\n        \u003c/select\u003e\n      \u003c/div\u003e\n    );\n  }\n}\nBrands.propTypes = {\n  brand: React.PropTypes.string\n};\nBrands.defaultProps = { brand: 'Volvo' };\n\nconst Cars = ({ cars = [], ready }) =\u003e (\n  \u003cul className={[\"cars\", ready ? \"ready\" : \"\"].join(' ')}\u003e\n    {cars.map((car, i) =\u003e\n      \u003cli className=\"car\" key={i}\u003e{car.brand} {car.model}\u003c/li\u003e\n    )}\n  \u003c/ul\u003e\n);\n\nif (Meteor.isClient) {\n  ReactDOM.render(\u003cBrands\u003e\u003cCars /\u003e\u003c/Brands\u003e, document.body);\n}\n\n```\n\nHere's an example on some CSS to show a loading icon when we're waiting for the cars to arrive to the client. We have also added a transition with a delay that we reset when the class ready is set, this is to avoid flashing the icon when the data is really fast, which is usually the case.\n\nAdd `Meteor._sleepForMs(2000);` in the publication to get view of the beautiful loading icon.\n\n```css\n\n.cars:before {\n  content: '';\n  display: block;\n  position: absolute;\n  top: 16px;\n  left: 0;\n  width: 100%;\n  height: 20px;\n  background: url(\"/loader.gif\") no-repeat center center;\n  background-size: auto 20px;\n  transition: opacity 0.1s ease 1s;\n  opacity: 1;\n}\n.cars.ready:before {\n  opacity: 0;\n  transition: none;\n}\n\n```\n\n### Add Server Side Rendering\n\nFirst off, remove the rendering to DOM from `main.jsx`:\n\n```javascript\nif (Meteor.isClient) {\n  ReactDOM.render(\u003cBrands\u003e\u003cCars /\u003e\u003c/Brands\u003e, document.body);\n}\n```\n\nAdd some packages, both Meteor and NPM.\n\n`meteor add kadira:flow-router-ssr`  \n`npm i --save react-mounter` (for React 0.14.7)\n\nIf you prefer React 15.x you can use react-mount-layout for that, a fork of react-mounter:\n`npm i --save react-mount-layout@^15.x` (for React 15.x, will replace with *react-mounter* when supporting React 15.x)\n\n```javascript\n// router.jsx\n\nimport React from 'react';\nimport { FlowRouter } from 'meteor/kadira:flow-router-ssr';\n\nconst MainLayout = ({content}) =\u003e (\n  \u003cmain\u003e{content}\u003c/main\u003e\n);\n\nFlowRouter.route(\"/\", {\n  action() {\n    ReactLayout.render(MainLayout, {\n      content: \u003cCars /\u003e\n    });\n  }\n});\n\n```\n\n#### Result on the server:\n\n```html\n\n\u003cmain\u003e\n  \u003cul class=\"cars\"\u003e\n    \u003cli\u003eVolvo XC90\u003c/li\u003e\n    \u003cli\u003eVolvo V90\u003c/li\u003e\n    \u003cli\u003eVolvo V70\u003c/li\u003e\n    \u003cli\u003eTesla Model S\u003c/li\u003e\n    \u003cli\u003eTesla Model X\u003c/li\u003e\n    \u003cli\u003eTesla Model 3\u003c/li\u003e\n    \u003cli\u003eTesla Roadster\u003c/li\u003e\n    \u003cli\u003eDeLorean DMC-12\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/main\u003e\n\n```\n\n# Using Tracker.Component (Meteor 1.2)\n\n## Installation\n\n`meteor add studiointeract:tracker-component@1.2.1`\n\nIn this example we render a couple cars from MongoDB.\n\n\u003e You'll probably recognize the autorun and subscribe from Blaze's Tracker implementation. That's the core idea, simplicity.\n\n```javascript\nModels = new Mongo.Collection('models');\n\nCars = class Cars extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.autorun(() =\u003e {\n      this.setState({\n        cars: Models.find().fetch()\n      });\n    })\n  }\n\n  render() {\n    let {cars = []} = this.state;\n    return (\n      \u003cul className=\"cars\"\u003e\n        {cars.map(car =\u003e\n          \u003cli className=\"car\"\u003e{car.brand} {car.model}\u003c/li\u003e\n        )}\n      \u003c/ul\u003e\n    );\n  }\n}\n\nif (Meteor.isClient) {\n  Meteor.startup(() =\u003e {\n    ReactDOM.render(\u003cCars /\u003e, document.body);\n  });\n}\n\n```\n\n## Fill with data from the server.\n\n\u003e Try adding new car models while running meteor, you'll notice it is fully reactive throughout the whole stack.\n\n```javascript\n// Bootstrap database with some cars.\nMeteor.startup(function() {\n  let models = {\n    \"Volvo\": ['XC90', 'V90', 'V70'],\n    \"Tesla\": ['Model S', 'Model X', 'Model 3', 'Roadster'],\n    \"DeLorean\": [\"DMC-12\"]\n  };\n\n  Object.keys(models).forEach(brand =\u003e {\n    models[brand].forEach(model =\u003e {\n      car = { brand: brand, model: model };\n      Models.upsert(car, car);\n    });\n  });\n});\n\n// Publish cars by brand or all of them.\nMeteor.publish('brand', (brand) =\u003e {\n  // Simulate network latency to show the loader.\n  // Meteor._sleepForMs(2000);\n  if (brand) {\n    return Models.find({ brand: brand });\n  }\n  return Models.find();\n});\n\n```\n\n### Result on the client:\n\n```html\n\n\u003cbody\u003e\n  \u003cul class=\"cars\"\u003e\n    \u003cli\u003eVolvo XC90\u003c/li\u003e\n    \u003cli\u003eVolvo V90\u003c/li\u003e\n    \u003cli\u003eVolvo V70\u003c/li\u003e\n    \u003cli\u003eTesla Model S\u003c/li\u003e\n    \u003cli\u003eTesla Model X\u003c/li\u003e\n    \u003cli\u003eTesla Model 3\u003c/li\u003e\n    \u003cli\u003eTesla Roadster\u003c/li\u003e\n    \u003cli\u003eDeLorean DMC-12\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/body\u003e\n\n```\n\n## Add Server Side Rendering\n\n`meteor add kadira:flow-router-ssr`  \n`meteor add kadira:react-layout`\n\n```javascript\n// router.jsx\n\nconst MainLayout = ({content}) =\u003e (\n  \u003cmain\u003e{content}\u003c/main\u003e\n);\n\nFlowRouter.route(\"/\", {\n  action() {\n    ReactLayout.render(MainLayout, {\n      content: \u003cCars /\u003e\n    });\n  }\n});\n\n```\n\n### Result on the server:\n\n```html\n\n\u003cmain\u003e\n  \u003cul class=\"cars\"\u003e\n    \u003cli\u003eVolvo XC90\u003c/li\u003e\n    \u003cli\u003eVolvo V90\u003c/li\u003e\n    \u003cli\u003eVolvo V70\u003c/li\u003e\n    \u003cli\u003eTesla Model S\u003c/li\u003e\n    \u003cli\u003eTesla Model X\u003c/li\u003e\n    \u003cli\u003eTesla Model 3\u003c/li\u003e\n    \u003cli\u003eTesla Roadster\u003c/li\u003e\n    \u003cli\u003eDeLorean DMC-12\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/main\u003e\n\n```\n\n## Full example: What about adding a loading gif?\n\n[http://github.com/studiointeract/tracker-component-example](http://github.com/studiointeract/tracker-component-example)\n\nWe got you're back on this one too! And have a look below, we've also added a select button to switch between selected car brand.\n\nJust add `this.subscriptionsReady()` to your autorun like below and you will get a reactive boolean to use for a ready flag.\n\nNotice! We advice in using \"ready\" flag rather \"loading\" due to that the data will default be ready when rendered on the server. The reason is basically to avoid having React complaining about different markup on server and client, which would happen when using the loading pattern.\n\n```javascript\n\nModels = new Mongo.Collection('models');\n\nCars = class Cars extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      brand: this.props.brand\n    };\n    this.autorun(() =\u003e {\n      this.subscribe( 'models', this.state.brand );\n    });\n    this.autorun(() =\u003e {\n      this.setState({\n        ready: this.subscriptionsReady(),\n        cars: Models.find({ brand: this.state.brand }).fetch()\n      });\n    });\n  }\n\n  handleChange() {\n    this.setState({brand: this.refs.brand.value});\n  }\n\n  render() {\n    let {cars = []} = this.state;\n    let selectBrand = this.handleChange.bind(this);\n    let brands = [\"Volvo\", \"Tesla\", \"DeLorean\"];\n\n    return (\n      \u003cdiv\u003e\n        \u003cselect ref=\"brand\" onChange={selectBrand} defaultValue={this.state.selected}\u003e\n          {brands.map((brand, i) =\u003e\n            \u003coption value={brand} key={i}\u003e{brand}\u003c/option\u003e\n          )}\n        \u003c/select\u003e\n        \u003cul className={[\"cars\",\n          this.state.ready ? \"ready\" : \"\"].join(' ')}\u003e\n          {cars.map((car, i) =\u003e\n            \u003cli className=\"car\" key={i}\u003e{car.brand} {car.model}\u003c/li\u003e\n          )}\n        \u003c/ul\u003e\n      \u003c/div\u003e\n    );\n  }\n}\nCars.propTypes = {\n  brand: React.PropTypes.string\n};\nCars.defaultProps = { brand: 'Volvo' };\n\n```\n\n## Increase Performance using PureRenderMixin\n\nAs described on its own [documentation](https://facebook.github.io/react/docs/pure-render-mixin.html) this is a utility to increase rendering performance for react components where\n\n* the render function is a pure function of its props\n* the props are not nested data structures (more on this on the docs)\n\nHere's the official ES6 example:\n\n```javascript\nimport PureRenderMixin from 'react-addons-pure-render-mixin';\nclass FooComponent extends React.Component {\n  constructor(props) {\n    super(props);\n    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);\n  }\n\n  render() {\n    return \u003cdiv className={this.props.className}\u003efoo\u003c/div\u003e;\n  }\n}\n```\n\n## Comparison\n\n|                 | Tracker.Component  | [TrackerReact](https://github.com/ultimatejs/tracker-react) | [ReactMeteorData](https://github.com/meteor/react-packages/tree/devel/packages/react-meteor-data)   | [react-komposer](https://github.com/kadirahq/react-komposer)                      |\n|:--------------- |:------------------:|:-----------------:|:----------------:|:--------------------:|\n| Lines of code   | 48                 | 148               | 200              | 292                  |\n| [ES6 Class Inheritance](#class-inheritance) | Yes | -    | -                | -                    |\n| [Composition](#composition) | Yes    | Yes               | [createContainer](http://guide.meteor.com/v1.3/react.html#using-createContainer) | Yes               |\n| [Mixin](#mixin) | -                  | -                 | Yes              | -                    |\n| [Subscriptions](#subscriptions) | this.subscribe | -     | -                | -                    |\n| [SSR](#server-side-rendering) | Yes  | Partial           | Partial          | Partial              |\n| Reactivity      | this.autorun       | render            | getMeteorData    | [composeWithTracker](https://github.com/kadirahq/react-komposer#using-with-meteor)                  |\n| NPM module      | Yes                | -                 | -                | Yes                  |\n\n## Server Side Rendering\n\nTo get the server to render your component with prefilled data, you will need to have that data with known methods (ReactMeteorData, createContainer and TrackerReact) to manually load specific for the server, this method can potentially render more data then the client expected from a subscription and React will definitely complain when the client version takes over.\n\nThe issue is that you have to match up the selectors for find() with the current subscription. With Tracker.Component which has subscription support built in, you setup these in the constructor together with your find() for the collection, this ensures the data available is equally specified on both server and client.\n\n## Subscriptions\n\nWith subscription management built in, your component will unsubscribe to the data you needed for the component when it is unmounted/destroyed, compared to known methods (ReactMeteorData, createContainer, TrackerReact and react-komposer) you will need to manage this yourself and potentially overload the client with data from multiple subscriptions that was never stopped, when the user is moving around your application.\n\nWith Tracker.Component you subscribe to publications per component like this:\n\n\u003e Notice! The `autorun` method is also reactive to changes on `this.props` and `this.state`, which makes it possible to react accordingly on changes to these and change the subscriptions.\n\n```javascript\nCars = class Cars extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      brand: this.props.brand\n    };\n    this.subscribe('brands');\n    this.autorun(() =\u003e {\n      this.subscribe( 'brand', this.state.brand );\n    });\n  }\n}\n```\n\n## Class Inheritance\n\nWith Class Inheritance we talk about the method we can extend existing Components with new functionality and a method of overloading existing method with your own, the benefits is that you are in full control of the component how it behaves and if you don't like how a particular method or handler does things, you can replace it with your own implementation.\n\n\u003e This is the default method for Tracker.Component because it requires you to write the least amount of code.\n\n## Composition\n\nWith Composition in React we mean the method to split up data management and pure rendering components, composition is actually a known method in mathematics, \"the pointwise application of one function to the result of another to produce a third function\" (ref. [Function Composition](https://en.wikipedia.org/wiki/Function_composition)).\n\nComposition can be achieved with known methods (createContainer, TrackerReact and react-komposer) by passing your data management function to the compostion method which resolves in a method that takes your Component as an argument.\n\nWith Tracker.Component this can be achivieved with (full example):\n\n```javascript\n// main.jsx\n\nimport React from 'react';\nimport Tracker from 'tracker-component';\n\nModels = new Mongo.Collection('models');\nif (Meteor.isServer) {\n  Meteor.publish('cars', brand =\u003e Models.find({ brand: brand }));\n}\n\nclass Composition extends Tracker.Component {\n  constructor(props) {\n    super(props);\n    this.subscribe('cars', this.props.brand);\n    this.autorun(() =\u003e {\n      this.setState({\n        cars: Models.find({ brand: this.props.brand }).fetch()\n      });\n    });\n  }\n}\n\nconst Cars = ({ cars = [] }) =\u003e (\n  \u003cul className=\"cars\"\u003e\n    {cars.map(car =\u003e\n      \u003cli className=\"car\"\u003e{car.brand} {car.model}\u003c/li\u003e\n    )}\n  \u003c/ul\u003e\n);\n\nif (Meteor.isClient) {\n  Meteor.startup(() =\u003e {\n    ReactDOM.render(\u003cComposition brand={ 'Volvo' }\u003e\u003cCars /\u003e\u003c/Composition\u003e, document.body);\n  });\n}\n```\n### Results:\n\n```html\n\n\u003cbody\u003e\n  \u003cul class=\"cars\"\u003e\n    \u003cli\u003eVolvo XC90\u003c/li\u003e\n    \u003cli\u003eVolvo V90\u003c/li\u003e\n    \u003cli\u003eVolvo V70\u003c/li\u003e\n  \u003c/ul\u003e\n\u003c/body\u003e\n\n```\n\n## Mixin\n\nMixins are a method of previous versions of React, we used them to extend the components with extra features on top, the new way to achive the same functionality is through [Composition](#composition) or [Class Inheritance](#class-inheritance). Don't forget to read the article on Mixins by Dan Abramov, [Mixins Are Dead. Long Live Composition](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750#.l18k55fdx).\n\n## Stopping computations\n\nUsually you don't need to stop the computation as it will automatically will be\nstopped when the component is destroyed, though notice that if you re-implement\ncomponentWillUnmount, be sure to call the super implementation as noticed below.\n\n\u003e Supported from version 1.3.18.\n\n### Alt 1: Stopping by reference.\n\nUse the returned reference to the computation and stop it from there.\n\n```js\nconst comp = this.autorun(() =\u003e {});\ncomp.stop();\n```\n\n### Alt 2: Stopping from inside the autorun.\n\nYou can always just pick up the reference to the computation passed in the\narguments of your autorun implementation and stop it.\n\n```js\nconst comp = this.autorun(c =\u003e {\n  c.stop();\n});\n```\n\n## Notes\n\nBeware, if you re-implement componentWillUpdate or componentWillUnmount, don't forget to call the super implementation (`super.componentWillUpdate()` or `super.componentWillUnmount()`).\n\n## Credits\n\nMade by the [creative folks at Studio Interact](http://studiointeract.com).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiointeract%2Ftracker-component","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstudiointeract%2Ftracker-component","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstudiointeract%2Ftracker-component/lists"}