React Example 5 - Instagram Picture Grid

Part of a tutorialzine article.

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.7.js"></script>
<script src="https://fb.me/react-dom-0.14.7.min.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>

CSS

* {
    padding:0;
    margin:0;
}

html{
    font:14px normal Arial, sans-serif;
    color:#626771;
    background-color:#fff;
}

body{
    padding:20px;
    text-align: center;
}

h1{
    font-size: 18px;
    margin-bottom: 30px;
    padding-top: 20px;
}

div.picture{
    display: inline-block;
    margin: 5px;
    cursor:pointer;
    position: relative;
}

div.picture.favorite:after{
    content: '❤';
    position: absolute;
    font-size: 80px;
    line-height: 200px;
    color: #FF224D;
    width: 100%;
    text-align: center;
    left: 0;
    text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
    font-weight: bold;
}

.pictures, .favorites{
    white-space: nowrap;
    overflow-y: auto;
    margin-bottom: 20px;
    height: 230px;
    background-color: #F3F3F3;
}

.pictures p, .favorites p {
    padding-top: 100px;
    font-size: 13px;
}

JavaScript 1.7

// In this example we also have two components - a picture and
// a picture list. The pictures are fetched from Instagram via AJAX.


var Picture = React.createClass({

    // This component doesn't hold any state - it simply transforms
    // whatever was passed as attributes into HTML that represents a picture.

    clickHandler: function(){
        
        // When the component is clicked, trigger the onClick handler that 
        // was passed as an attribute when it was constructed:

        this.props.onClick(this.props.id);
    },

    render: function(){

        var cls = 'picture ' + (this.props.favorite ? 'favorite' : '');

        return (

            <div className={cls} onClick={this.clickHandler}>
                <img src={this.props.src} width="200" title={this.props.title} />
            </div>

        );

    }

});

var PictureList = React.createClass({

    getInitialState: function(){
        
        // The pictures array will be populated via AJAX, and 
        // the favorites one when the user clicks on an image:
        
        return { pictures: [], favorites: [] };
    },

    componentDidMount: function(){
        
        // When the component loads, send a jQuery AJAX request

        var self = this;

        // API endpoint for Instagram's popular images for the day

        var url = 'https://api.instagram.com/v1/media/popular?client_id=' + this.props.apiKey + '&callback=?';

        $.getJSON(url, function(result){

            if(!result || !result.data || !result.data.length){
                return;
            }

            var pictures = result.data.map(function(p){

                return { 
                    id: p.id, 
                    url: p.link, 
                    src: p.images.low_resolution.url, 
                    title: p.caption ? p.caption.text : '', 
                    favorite: false 
                };

            });

            // Update the component's state. This will trigger a render.
    ...