react-side-effect
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -0,1 +1,3 @@ | ||
'use strict'; | ||
var React = require('react'), | ||
@@ -5,3 +7,3 @@ invariant = require('react/lib/invariant'), | ||
function createSideEffect(onChange, options) { | ||
function createSideEffect(onChange, mixin) { | ||
invariant( | ||
@@ -21,2 +23,4 @@ typeof onChange === 'function', | ||
return React.createClass({ | ||
mixins: [mixin], | ||
statics: { | ||
@@ -23,0 +27,0 @@ dispose: function () { |
{ | ||
"name": "react-side-effect", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Create components whose prop changes map to a global side effect", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,2 +0,2 @@ | ||
# react-side-effect | ||
# React Side Effect | ||
Create components whose prop changes map to a global side effect. | ||
@@ -10,7 +10,49 @@ | ||
## Use Cases | ||
* Setting `document.style.overflow` or background color depending on current screen; | ||
* Firing Flux actions using declarative API depending on current screen; | ||
* Some crazy stuff I haven't thought about. | ||
## How's That Different from `componentDidUpdate`? | ||
It gathers current props across *the whole tree* before passing them to side effect. For example, this allows you to create `<BodyStyle style>` component like this: | ||
```js | ||
// RootComponent.js | ||
return ( | ||
<BodyStyle style={{ backgroundColor: 'red' }}> | ||
{this.state.something ? <SomeComponent /> : <OtherComponent />} | ||
</BodyStyle> | ||
); | ||
// SomeComponent.js | ||
return ( | ||
<BodyStyle style={{ backgroundColor: this.state.color }}> | ||
<div>Choose color: <input valueLink={this.linkState('color')} /></div> | ||
</BodyStyle> | ||
); | ||
``` | ||
and let the effect handler merge `style` from different level of nesting with innermost winning: | ||
```js | ||
var BodyStyle = createSideEffect(function handleChange(propsList) { | ||
var style = {}; | ||
propsList.forEach(function (props) { | ||
Object.assign(style, props.style); | ||
}); | ||
for (var key in style) { | ||
document.style[key] = style[key]; | ||
} | ||
}); | ||
``` | ||
## API | ||
#### `createSideEffect: (onChange: Array<Props> -> ()) -> ReactComponent` | ||
#### `createSideEffect: (onChange: Array<Props> -> (), mixin: Object?) -> ReactComponent` | ||
Returns a component that, when mounted, unmounted or having received new props, calls `onChange` with each mounted component's `props`. | ||
Returns a component that, when mounting, unmounting or receiving new props, calls `onChange` with `props` of **each mounted instance**. | ||
It's up to you to `reduce` them, use innermost values, or whatever you fancy. | ||
@@ -21,5 +63,7 @@ | ||
You can use optional second `mixin` parameter to specify `propTypes`, `displayName` or `statics`. It will be mixed into the generated component. | ||
## Usage | ||
Here's how to implement [React Document Title](https://github.com/gaearon/react-document-title) using React Side Effect: | ||
Here's how to implement [React Document Title](https://github.com/gaearon/react-document-title) (both client and server side) using React Side Effect: | ||
@@ -30,3 +74,3 @@ ```js | ||
var React = require('react'), | ||
createSideEffect = require('./createSideEffect'); | ||
createSideEffect = require('react-side-effect'); | ||
@@ -49,3 +93,3 @@ /** | ||
*/ | ||
var SetDocumentTitle = createSideEffect(function handleChange(propsList) { | ||
var DocumentTitle = createSideEffect(function handleChange(propsList) { | ||
var title = extractTitle(propsList); | ||
@@ -58,8 +102,5 @@ | ||
} | ||
}); | ||
}, { | ||
displayName: 'DocumentTitle', | ||
/** | ||
* Create a wrapper for it with propTypes, displayName and helpers for server and testing. | ||
*/ | ||
var DocumentTitle = React.createClass({ | ||
propTypes: { | ||
@@ -82,9 +123,5 @@ title: React.PropTypes.string.isRequired | ||
var title = _serverTitle; | ||
SetDocumentTitle.dispose(); | ||
this.dispose(); | ||
return title; | ||
} | ||
}, | ||
render: function () { | ||
return React.createElement(SetDocumentTitle, this.props); | ||
} | ||
@@ -91,0 +128,0 @@ }); |
6358
5
47
126