Git Product home page Git Product logo

react-stampit's Introduction

Build Status

react-stampit

A specialized stampit factory for React.

Create React components in a way analogous to React.createClass, but powered by a subset of the stampit API.

Install

react-stampit can be installed via npm

npm install react-stampit

or by downloading the latest release.

What is this

This library is the result of wondering about what other ways a React component could be represented. Stamps are a cool concept, and more importantly have proven to be a great alternative to React.createClass and the ES6 class due to their flexibility and use of multiple kinds of prototypal inheritance.

react-stampit has an API similar to React.createClass. The factory accepts two parameters, the React library and a description object.

stampit(React, {
  init: [],
  state: {},
  statics: {},

  // convenience props for React statics
  contextTypes: {},
  childContextTypes: {}.
  propTypes: {},
  defaultProps: {},

  // ...methods
});

The best part about stamps is their composability. What this means is that n number of stamps can be combined into a new stamp which inherits each passed stamp's behavior. This is perfect for React, since class is being pushed as the new norm and does not provide an idiomatic way to use mixins. (classical inheritance ๐Ÿ˜ž). While stamp composability on the surface is not idiomatic, the conventions used underneath are; it is these conventions that provide a limitless way to extend any React component.

mixin1.jsx

export default {
  componentWillMount() {
    this.state.mixin1 = true;
  },
};

mixin2.jsx

export default {
  componentWillMount() {
    this.state.mixin2 = true;
  },
};

component.jsx

import stampit from 'react-stampit';
import * as cache from 'react-stampit/utils/cache';

const id = cache.uniqueId();

export default React => {
  return cache.find(id) || cache.save(
    stampit(React, {
      state: {
        comp: false,
        mixin1: false,
        mixin2: false,
      },

      _onClick() {
        return this.state;
      },

      componentWillMount() {
        this.state.comp = true;
      },

      render() {
        return <input type='button' onClick={() => this._onClick()} />;
      },
    }), id
  );
};

app.jsx

import React from 'react';

import componentFactory from './component';
import mixin1 from './mixin1';
import mixin2 from './mixin2';

const Component = componentFactory(React).compose(mixin1, mixin2);

/**
 * Do things
 */
shallowRenderer.render(<Component />);
const button = shallowRenderer.getRenderOutput();

assert.deepEqual(
  button.props.onClick(), { comp: true, mixin1: true, mixin2: true },
  'should return component state with all truthy props'
);
  >> ok

You may have noticed several interesting behaviors.

  • component is a factory

This design pattern is optional, but recommended. Component factories are react-stampit's solution for avoiding the often hard to debug problems created by multiple instances of React. Read more about that here. By injecting the React library, we are able to guarantee the version and instance of React that a component will receive.

  • caching

This goes hand in hand with designing components as factories. Node.js's internal caching will not work as expected for component factories, react-stampit's cache utility can be used as a replacement.

  • no autobinding

Event handlers require explicit binding. No magic. This can be done using .bind or through lexical binding with ES6 arrow functions as shown in the example.

  • no call super

React methods are wrapped during composition, providing functional inheritance. Sweet.

  • mixins are POJOs

This is shorthand syntax for:

stampit(null, {
  // stuff
});

If you feel limited by class, or want a fresh take on React.createClass, maybe give react-stampit a try and learn more about what stampit is all about. And please report any issues you encounter!

Docs

Examples

Pending Issues

License

MIT

react-stampit's People

Contributors

troutowicz avatar josephclay avatar

Watchers

Josh David Miller avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.