npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-immutable-cursor

v0.1.2

Published

A React helper allowing for intuitive bidirectional data flow, through the use of cursors into a single, immutable root atom.

Downloads

9

Readme

React Immutable Cursor

Circle CI npm version

A React helper allowing for intuitive bidirectional data flow, through the use of cursors into a single, immutable root atom.

Rationale

The organisation and management of application-level state in a project can be complex. React itself promotes the concept of top-down rendering through component composition (thus resulting in the same directional flow of data). However, data must have the ability to flow bidirectionally to provide a useful application - i.e a button deeply nested in the component tree that submits a new record in a list.

I've tried several ideas to solve this issue, including the flux architecture, however it has some conceptual problems.

Why I built it

I wanted:

  • to incorporate a single, root-level atom as my application state

    This would allow me keep all my state at the very fringes of my applicaton, and means my components can become (essentially) pure, referentially-transparent functions. This backing structure also needed to be immutable, so I could make performance alterations to the application using reference-based object equality checks in shouldComponentUpdate().

  • to use an elegant, idiomatic interface to communicate with the above

    I needed some way to communicate reads and writes to the aforementioned backing structure, but I didn't want to compromise it's API design due to the store being of an immutable type.

  • require as little integration as possible in my React application

    The elegance of the solution would be gauged by the level of effort required to integrate it into an existing React application.

The solution

Cursors over an immutable backing structure, instantiated using a React component class!

How do cursors work?

A model borrowed from Om (a ClosureScript interface to React), a cursor provides a mutative API that holds a scoped reference to a particular sub atom in the application state. Once created, this sub-atom can be updated from any cursor that holds a reference to it. Cursors can also be derived from one another, which make them incredibly powerful.

I've always been taken with the Immutable JS library and have been watching the development of their cursor implementation closely. An an issue has recently been fixed that until now, meant they couldn't be used in the context of an application architecture like React.

How to use

Root-level component

Below is a barebones setup of a root-level component within your application.

import React from 'react/addons';
import Root from 'react-immutable-cursor';

// Extend your own component from the class provides by react-immutable-cursor
export default class extends Root {

  // The return value of this.createAtom() will be the root-level cursor.
  state = this.createAtom();

  // Make sure you define an initialState method that returns an object. This object will form the root backing structure.
  initialState() {
    return {
      people: this.props.people,
      pending: null,
      canManage: this.props.canManage,
      projects: {
        booked: this.props.projects.booked,
        unbooked: this.props.projects.unbooked
      }
    };
  }

  render() {
    // This is where the root cursor currently lives, although this will change soon.
    const cursor = this.state.cursor
    return (
      <div id="timesheet">
        <Heading people={cursor.get('people')} />
        <UnbookedList people={cursor.get('people')} projects={cursor.getIn(['projects', 'unbooked'])}/>
        <BookedList people={cursor.get('people')} projects={cursor.getIn(['projects', 'booked'])}/>
  }

}

Deriving and using cursors

Building on the above, below would be the BookedList component.

import React from 'react/addons';
import Root from 'react-immutable-cursor';

export default class extends React.Component {

  addBooking(e) {
    // Using Immutabile JS' mutative API, we're calling .push() directly on this
    // sub cursor. This is an update action, this will cause a new, updated immutable
    // backing structure at the root-level and will trigger a re-render of the
    // entire application.
    this.props.projects.push({
      name: 'Some name',
      id: Math.random()
    })
  }

  render() {
    return (
      <div>
        <ul>
          {this.props.projects.map((project) => {
            <li>
              {booking.get('name')} // This would return a primitve
            </li>
          })}
        </ul>
        <button onClick={this.addBooking.bind(this)}>Add booking</button>
      </div>
    )
  }
}

Who's this for?

  • People who are sick of prop callback hell
  • People who have tried Flux but have experienced it's disadvantages at scale.
  • People who want to further embrace the idea of functional programming, and thus reap the rewards that this gives.