elegant-react

Functional React Architecture inspired by omniscient and browser.html. Comments/suggestions/PRs are all welcome. This is still experimental.

BTW, you might also find it useful to use this in conjunction with react-derive. And check out elegant-react-hot-demo which combines them.

what is elegant-react?

elegant-react is an npm package. The source code for the npm package is in the src/ directory of this repo.

This github repo is also currently the home for a growing number of experiments related to React functional patterns. The code for these experiments live in the examples/ dir. Some use the elegant-react npm package but others, for the sake of simplicity, do not.

The elegant-react npm package provides:

    const subedit = (edit, ...path) => transform =>
        edit(state => state.updateIn(path, transform));

about

This repo started off as a demonstration of some concepts that I wrote about in this Medium article and this one as well. However, since that time elegant-react has continued to evolve and things have changed significantly. For the purpose of education, you can check out the elegant-react-og repo which is a copy of the elegant-react repo immediately before it began to diverge from the content in those two Medium articles.

Installation

Install via npm

npm install elegant-react

Bringing it into your project

Import it:

import {elegant, subedit} from 'elegant-react';

Or if you'd like to enable debug mode:

import ElegantReact from 'elegant-react';
const {elegant, subedit} = ElegantReact({debug: true});

Note: the subedit function is also available as sub. It's a personal preference which you use. I like the way that sub(edit, 'foo') reads.

react-native support

Require it:

import {elegant, subedit} from 'elegant-react/native';

Or if you'd like to enable debug mode:

import ElegantReact from 'elegant-react/native';
const {elegant, subedit} = ElegantReact({debug: true});

Using in codepen, jsbin, etc.

Add the script:

//rawgit.com/gilbox/elegant-react/master/build/global/elegant-react.js

This exposes the global object ElegantReact.

const {elegant, subedit} = ElegantReact;

Or if you'd like to enable debug mode:

const {elegant, subedit} = ElegantReact({debug: true});

Usage

First, make sure you understand the subedit (aka sub) function described in this Medium article

Then add the @elegant decorator to your component, specifying which props are static.

const inc = n => n + 1;

@elegant({statics: ['editValue']})
class Item extends Component {
  render() {
    const {item,editValue} = this.props;
    const onClick = _ => editValue(inc);
    return <li onClick={ onClick }>
      { item.get('name') } - { item.get('value') }
    </li>
  }
}

Now put that component to use:

const reverse = data => data.reverse();

@elegant({statics: ['edit']})
class Items extends Component {
  render() {
    const {items,edit} = this.props;

    const children = items.toArray().map(
      (item, index) =>
        <Item key={item.get('name')}
              item={item}
              editValue={sub(edit, index,'value')} /> );

    return  <div key="root">
      <button onClick={_ => edit(reverse)}>reverse</button>
      <ul>{ children }</ul>
    </div>;
  }
}

The rest of the source for this demo is here and you can see it in action as well.

dependencies

You might notice that elegant-react has no dependencies nor peerDependencies listed in it's package.json file. This is so it can support both react and react-native from the same npm package.

Although it's not a hard dependency, the provided subedit function is known to work with immutable-js. If you wish to use a different immutable lib, just create your own subedit function and it should work.

    const subedit = (edit, ...path) => transform =>
        edit(state => mori.updateIn(state, path, transform));

Run the examples

Clone this repo, then:

npm install
npm run examples

... and navigate to http://localhost:8080/webpack-dev-server/

differences from omniscient

live examples

credit

This project was originally a simplified version of omniscient which promotes the functional approach of browser.html. However, it has since evolved to become a more unique thing of it's own (see differences from omniscient above)