JSFiddle - React, Tailwind, and code Playground

by insin

HTML

<script src="http://fb.me/JSXTransformer-0.10.0.js"></script>
<script src="http://fb.me/react-with-addons-0.10.0.js"></script>
<script src="http://fb.me/react-js-fiddle-integration.js"></script>

JavaScript 1.7

/** @jsx React.DOM */

//
// THIS IS THE IMPLEMENTATION: FEEL FREE TO SKIP!
//

// TODO: cancel inflight requests when route changes or when component unmounts
// TODO: allow user error handling (in state perhaps)
var DataFetchingMixin = {
    propTypes: {
        initialData: React.PropTypes.object,
        route: React.PropTypes.string.isRequired
    },
    getDefaultProps: function() {
        return {initialData: null};
    },
    getInitialState: function() {
        return {data: this.props.initialData};
    },
    componentDidMount: function() {
        if (!this.state.data) {
            this.constructor.fetchData(this.props.route, function(data) {
                this.setState({data: data});
            }.bind(this));
        }
    },
    componentWillReceiveProps: function(nextProps) {
        if (this.props.route !== nextProps.route) {
            this.setState({data: null}); // TODO: set to nextProps.initialData?
            this.constructor.fetchData(nextProps.route, function(data) {
                this.setState({data: data});
            }.bind(this));
        }
        if (this.props.initialData !== nextProps.initialData && nextProps.initialData) {
            throw new Error('initialData may never change to non-null!');
        }
    },
    statics: {
        renderComponentToString: function(route, cb) {
            this.fetchData(route, function(data) {
                cb(data, React.renderComponentToString(this({route: route, initialData: data})));
            }.bind(this));
        }
    }
};

//
// HERE IS AN EXAMPLE!
//

var Hello = React.createClass({
    mixins: [DataFetchingMixin],
    statics: {
        fetchData: function(route, cb) {
            $.get('http://foaas.com/shakespeare/' + route + '/React', function(text) {
                cb({text: text});
            });
        }
    },                
    render: function() {
        if (!this.state.data) {
            return <div>Loading...</div>;
        }
        return <div>All I...