App as Function

Starting point for creating JSFiddles with React. This uses React with Addons.

by justindeal

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-0.14.0.js"></script>
<script src="https://fb.me/react-dom-0.14.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

JavaScript 1.7

const actionTypes = {
	INIT: 'INIT',
	SET_NAME: 'SET_NAME'
};

let sendAction;

// Generic handler to feed actions to the action stream.
const sendAction$ = Rx.Observable.create(observer => {
	sendAction = action => {
    	observer.onNext(action);
    };
});

// Just a silly component.
const Greet = props => (
	<div>
    	Name: <input type="text" value={props.name}
        	onChange={(event) => sendAction({
            	type: actionTypes.SET_NAME,
                name: event.target.value
            })}
        />
        <p>Hello, {props.name || 'Unknown'}</p>
        <p>Total # of changes: {props.changeCount}</p>
    </div>
);

// Our app takes an action stream and returns a view stream.
const app = action$ => {
    
    // Make a state/action stream, counting the total number of
    // changes made.
    const actionAndState$ = action$.startWith({
    	changeCount: -1
    }).scan((prev, action) => {
    	return {changeCount: prev.changeCount + 1, action};
    }).slice(1);
    
    // Map our action/state stream to views.
    return actionAndState$.map(actionAndState => {
    	const {action, changeCount} = actionAndState;
    	const name = action.type === actionTypes.INIT ? '' : action.name;
    	return <Greet name={name} changeCount={changeCount}/>;
    });
};

// Render veiws as they arrive.
app(sendAction$).forEach(view => {
	ReactDOM.render(
    	view,
    	document.getElementById('container')
	);
});

// Prime the pump.
sendAction({type: actionTypes.INIT});