# react-mutant

> An easy way to update props in ReactJS

Latest version **0.1.0** (published 2015-02-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-mutant
pnpm add react-mutant
yarn add react-mutant
bun add react-mutant
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.0 |
| Published | 2015-02-25 |
| First published | 2015-02-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Jesse Drelick |
| Maintainers | jessedrelick |
| Keywords | reactjs, setProps, cortex |

## Links

- npm: https://www.npmjs.com/package/react-mutant
- npm.io page: https://npm.io/package/react-mutant

## Recent versions

- 0.1.0 (latest) — 2015-02-25

## README

# React-Mutant 

React-Mutant piggybacks your props to make nested updates easy in React. Instead of passing 'update' handlers into all components needing to update root component properties, React-Mutant can be used instead.

* Simpler solution than Flux, though not as robust. Ideal for smaller to mid-size applications or isolated components
* Inspired by Cortex <http://https://github.com/mquan/cortex>
* Built-in listener for root component/top-down updates
* Provide your own mixin methods to extend the React-Mutant instance

# Example

JSFiddle Live Example: <http://jsfiddle.net/69z2wepo/2975/>

	// Create Mutant Objects with default properties
	var postMutant = new Mutant({
		id: 0,
		title: "",
		content: ""
	});
	var commentsMutant = new Mutant({
		comments: []
	});
	
	// Root-level component
	var App = React.createClass({
	    // validate properties as your normally would
	    propTypes: {
	        post: React.PropTypes.shape({
	            id: React.PropTypes.number,
	            title: React.PropTypes.title,
	            content: React.PropTypes.content
	        }),
	        comments: React.PropTypes.shape({
	            comments: React.PropTypes.array
	        })
	    },
	    // set default props to Mutant objects
	    getDefaultProps: function () {
			return {
				post: postMutant,
				comments: commentsMutant
			}
		},
	    // listen to 'update' events, pass in updated mutant and set root props to new mutant
	    componentWillMount: function () {
	        var self = this;
	        postMutant.mutant.on("update", function (newMutant) {
	            self.setProps({post: newMutant});
	        });
	        commentsMutant.mutant.on("update", function (newMutant) {
	            self.setProps({comments: newMutant});
	        });
	    },
	    // {...this.props.post} = mutant object we created for post
	    // {...this.props.comments} = mutant object we created for comments
		render: function () {
	        return (
				<div className="app">
					<Post {...this.props.post} />
					<Comments {...this.props.comments} />
				</div>
			);
		}
	});

	var Post = React.createClass({
		componentDidMount: function () {
		  // once mounted, use post.mutant.set to update props and trigger root-level 'update'
	        this.props.mutant.set({id: 1, title: "title", content: "content"});
	    },
	    render: function () {
			return (
				<div className="post">
					<h1>{this.props.title}</h1>
					<p>{this.props.content}</p>
				</div>
			);
		}
	});

	var Comments = React.createClass({
		add: function () {
	        var current = this.props.comments;
	        current.push({username: "me", date: "now", comment: "comment"});
	        this.props.mutant.set({comments: current});
	    },
	    remove: function (index, e) {   
	        var current = this.props.comments;
	        current.splice(index, 1);
	        this.props.mutant.set({comments: current});
	    },
	    render: function () {
			var i = -1;
	        var remove = this.remove;
	        var comments = this.props.comments || [];
			var list = comments.map(function (comment) {
				i++;
	            comment.index = i;
	            return <Comment key={i} {...comment} remove={remove} />
			});
			return (
				<div className="comments">
	                <button onClick={this.add}>Add Comment</button>
					{list}
				</div>
			);
		}
	});

	var Comment = React.createClass({
	    propTypes: {
			index: React.PropTypes.number,
	        username: React.PropTypes.string,
			date: React.PropTypes.string,
			comment: React.PropTypes.string
		},
		render: function () {
			return (
				<div className="comment">
	                <div>{this.props.index}</div>
					<div>{this.props.username}</div>
					<div>{this.props.date}</div>
					<div>{this.props.comment}</div>
	                <button onClick={this.props.remove.bind(null, this.props.index)}>Remove</button>
				</div>
			);
		}
	});

	React.render(<App />, document.getElementById("app"));


# Cortex comparison

Feature		| Mutant	| Cortex
----------------|---------------|----------
Access prop values | Standard | .getValue()
Works with React PropType validation out of the box | Yes | No
Array & Hash methods | No | Yes
Update Root Component easily | Yes | Yes
Callbacks | Yes | Yes
Deeply Nested Updates | Not yet | Yes
.getChanges() | .history() instead | Yes
.didChange() | .set() returns false instead | Yes
Batch updates | Not Yet | Yes
.remove() | No | Yes
NPM | Yes | Yes
ES6 | No | Yes
Bower | No | Yes
CDN | Not Yet | No

# Key Differences

The three primary reasons for creating React-Mutant over Cortex are:

1. No need to use .getValue() when accessing prop values
2. Works with React.PropTypes validation out of the box
3. Lighter objects by not including Hash/Array methods

# Nested Updates
Also, though not currently supported, future releases would like to include deeply nested updates. 

So instead of:

    mymutant.mutant.set({root: {level1: {level2: {level3: "newvalue"}}}});

You'll be able to:

    mymutant.mutant.root.level1.level2.level3.set("newvalue");

---
_Source: https://npm.io/package/react-mutant · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
