React tutorial: How to build the Instagram UI with React

Apr 28, 2021 - 10 min read
Ryan Thelin
editor-page-cover

Portfolio projects are a key part of landing an interview as a front-end developer or full-stack developer. While you could have many smaller projects, it often looks better to have only a few long-term projects, like replicating popular social media or messaging apps. These long-term projects show recruiters that you have experience working with their type of product and that you have the determination to keep working on it.

Today, we’ll help you get started recreating Instagram by building its UI using React. By the end of this tutorial, you’ll have a great starting point for your next portfolio-building project.

Here’s what we’ll cover today:


Transition to React with hands-on practice

Use practice projects and in-code examples to learn professional React in half the time.

React for Front-End Developers


Prerequisites

To get started you’ll need both Node and Node Package Manager installed on your device.

Enter the following commands into your command prompt to confirm they’re installed:

    node --version
    npm --version

You’ll need Node Version 6 or higher to install React. To install React, enter the following into your command prompt:

npm install -g create-react-app

Setting up your React project

To start, we’ll create our web app and name it instagram-clone. Enter the following command:

create-react-app instagram-clone

This will create a default app template that we’ll use as our starting point. You can view the default homepage by first selecting the app directory and starting the selected directory.

cd instagram-clone
npm start

Wait for the server to start then go to localhost:3000 in your browser to see the app template:

widget

Create UI components

Now we can start customizing the template to look like the Instagram UI. We’ll use React Web Components to construct the app header, which will contain the Instagram logo and brand name, and the post component, which will contain the posted image, the username, and a caption.

As a refresher, React has a library of pre-built components that include the basic structure for common app behaviors like headers or search bars. Finish React UIs are made up of multiple of these web components that you can individually customize and reused in other pages or projects.

We’ll start by creating and styling the Header component.


Header component

We need to make the components folder in the src/ directory of our application to hold our Header component.

The following command selects the src/ directory, creates a new folder within, and selects that new components folder:

cd src
mkdir components && cd components

We’ll then create and select a folder for the Header component within components using:

mkdir Header && cd Header

From here, we’ll create our index.js file that lets us describe the content of the component using JSX, a JavaScript-enhanced version of HTML.

touch index.js

Now open the index.js file and paste the following code:


    // src/components/Header/index.js

    import React from "react";

    

    class Header extends React.Component{

        render(){

            return (

               <nav className="Nav">

                 <div className="Nav-menus">

                   <div className="Nav-brand">

                     <a className="Nav-brand-logo" href="/">

                       Instagram

                     </a>

                   </div>

                 </div>

               </nav>

           );

        }   

    }

    export default Header;

This code creates the outline of all the content we’ll have in the component but does not include any styling.

To make it visually appealing, we’ll have to create a CSS style sheet in our Header component directory.

touch Header.css

Open your CSS style sheet and paste the following:


    /* src/components/Header/Header.css */

    i.Nav {

      background-color: #fff;

      border-bottom: 1px solid rgba(0, 0, 0, 0.0975);

      position: fixed;

      top: 0;

      width: 100%;

      z-index: 2;

      -webkit-transition: height 0.2s ease-in-out;

      transition: height 0.2s ease-in-out;

      height: 77px;

    }

    .Nav-menus {

      display: flex;

      flex-direction: row;

      height: 77px;

      width: 70%;

      margin: 0 auto;

      padding: 26px 40px;

    }

    .Nav-brand-logo {

      display: block;

      background-position: -176px 0px;

      background-image: url(../../logo.png);

      background-size: 405px 379px;

      background-repeat: no-repeat;

      height: 35px;

      width: 176px;

      text-indent: -1000%

    }

background-image imports an image from a URL. You’ll need to include the URL for the logo in the src directory using this format: [logo.png](<URL>)

With the appropriate styling made, update your index.js file to reference the style sheet.


    // src/components/Header/index.js

    import React from "react";

    import "./Header.css";

    class Header extends React.Component{

        render(){

            return (

               <nav className="Nav">

                 <div className="Nav-menus">

                   <div className="Nav-brand">

                     <a className="Nav-brand-logo" href="/">

                       Instagram

                     </a>

                   </div>

                 </div>

               </nav>

           );

        }   

    }

    export default Header;

We’re now ready to render our component and see how it looks. Simply replace the code in your src/App.js file with the following code:


    // src.App.js

    import React, { Component } from 'react';

    import './App.css';

    import Header from './components/Header';

    class App extends Component {

      render() {

        return (

          <Header />

        );

      }

    }

    export default App;

This essentially tells the app to display the Header as a regular feature of the page.

To see how the Header turned out, start the app again and navigate to localhost:3000 again. You should see our awesome new Header!

widget

Post Component

Now let’s add the Posts component. This component will set the format for Instagram’s iconic block-post design and will allow users to post images with a caption under their username.

As we did with Header, we’ll start by creating a new folder called Post in the components directory.


cd src/components

mkdir Post && cd Post

Then we’ll create the index.js file within the Post folder:


touch index.js

Within index.js file, paste the following:


    // src/components/Post/index.js

    import React, { Component } from "react";

    class Post extends Component {

      render() {

        return <article className="Post" ref="Post">

            <header>

              <div className="Post-user">

                <div className="Post-user-profilepicture">

                  <img src="https://t4.ftcdn.net/jpg/02/19/63/31/360_F_219633151_BW6TD8D1EA9OqZu4JgdmeJGg4JBaiAHj.jpg" alt="John D. Veloper" />

                </div>

                <div className="Post-user-nickname">

                  <span>John Doe</span>

                </div>

              </div>

            </header>

            <div className="Post-image">

              <div className="Post-image-bg">

                <img alt="Icon Living" src="[https://cdn-images-1.medium.com/max/1200/1*dMSWcBZCuzyRDeMr4uE_og.png]" />

              </div>

            </div>

            <div className="Post-caption">

              <strong>John D. Veloper </strong> Loving Educative!

            </div>

          </article>;

        }

    }

    export default Post;

This index.js file outlines three content areas:

  • Post Header - which shows the profile picture and username

  • Post Content - displays the posted image

  • Post Caption - displays the username and the caption

Without styling, this will just look like a jumble of text and an image. Let’s add a CSS style sheet, Post.css in the Post directory.

Create a Post.css file by entering:


touch Post.css

Now open the CSS style sheet and paste the following code:

    /* src/components/Post/Post.css */

    .Post {

      border-radius: 3px;

      border: 1px solid #e6e6e6;

      background-color: #fff;

      margin-bottom: 60px;

      margin-left : 20%;

      margin-right: 20%;

    }

    .Post-user {

      display: flex;

      padding: 16px;

      align-items: center;

    }

    .Post-user-profilepicture {

      width: 30px;

      height: 30px;

    }

    .Post-user-profilepicture img {

      width: 100%;

      height: 100%;

      border-radius: 50%;

    }

    .Post-user-nickname {

      margin-left: 12px;

      font-family: 'PT Sans', sans-serif;

      font-weight: bold;

    }

    .Post-image-bg {

      background-color: #efefef;

    }

    .Post-image img {

      display: block;

      width: 100%;

    }

    .Post-caption {

      padding: 16px 16px;

    }

    .Post-caption strong {

      font-family: 'PT Sans', sans-serif;

      font-weight: bold;

    }

    .vjs-fade-out {

      display: none;

      visibility: hidden;

      opacity: 0;

    }

As before, now we add an import statement at the top of the index.js file in the Post folder.


import "./Post.css";

Now we have to tell the application to render our Post component. We’ll edit the same App.js file to now look like:


    // src/App.js

    import Post from './components/Post';

    class App extends Component {

      render() {

        return (

          <div>

            <Header />

            <div>

              <Post />

            </div>

          </div>

        );

      }

    }

    export default App;

Finally, start the app and go to localhost:3000.

widget

With just those two components, our Instagram app is looking pretty realistic!


Keep practicing React.

Build your React portfolio without scrubbing through videos or documentation. Educative’s text-based courses are easy to skim and feature live coding environments - making learning quick and efficient.

React for Front-End Developers


Upgrading your app with properties

In our current build, we use static pictures and an account to test the Post component. If we keep it this way, all of our posts will be the same. Now we’ll add props to our Posts component to allow them to populate dynamically.

Properties, or props, are essentially variables within a component that let you share data between components. This helps make a component reusable because we don’t need a new component for each post.

Update the index.js file in your Post component to look like this:


    // src/components/Post/index.js

    import React, { Component } from "react";

    import "./Post.css";

    class Post extends Component {

        constructor(props){

            super(props);

        }

      render() {

        const nickname = this.props.nickname;

        const profilepicture= this.props.profilepicture;

        const image = this.props.image;

        const caption = this.props.caption;

        return (

          <article className="Post" ref="Post">

            ...

                <img src={profilepicture} alt={nickname} />

            ... 

                  <span>{nickname}</span>

            ...

                <img alt={caption} src={image} />

            ...

              <strong>{nickname}</strong>{caption}

            ...

          </article>

        );

      }

    }

    export default Post;

This adds props, marked by curly braces {}, for each piece of content in the Post. These are assigned values at rendering to allow for unique posts.

As a final step, we need to change App.js to pass the required data to the Post component.


    // src/App.js

    import React, { Component } from 'react';

    import './App.css';

    import Header from './components/Header';

    import Post from './components/Post';

    class App extends Component {

      render() {

        return <div className="App">

            <Header />

            <section className="App-main">

              <Post nickname="John D. Veloper" profilepicture="https://t4.ftcdn.net/jpg/02/19/63/31/360_F_219633151_BW6TD8D1EA9OqZu4JgdmeJGg4JBaiAHj.jpg" caption="Loving Educative!" image="https://cdn-images-1.medium.com/max/1200/1*dMSWcBZCuzyRDeMr4uE_og.png" />

            </section>

          </div>;

      }

    }

    export default App;

While the page will look the same at localhost:3000, you now have an interesting app UI that can load unique posts!


Next steps for your Instagram app

Congratulations on finishing your Instagram UI! While not app store ready yet, this is a great starting point for a longer project for your professional portfolio.

Here are some more functionalities you can add next to improve your developer skills:

  • Back-end fetch integration with Graph QL or Firebase

  • Add real-time an Instagram Story feature

  • Create tabs and account pages that pull previous posts

  • Add login authentication with Firestore

  • Add an Instagram Messenger feature with emoji support

If you get stuck, try uploading your project on Github for feedback from other developers! The React community is very active and will help you find your next steps.

To help you continue your hands-on React learning, Educative has created the React for Front-End Developers Path. This all-in-one learning material collection will teach you the fundamental skills front-end dev recruiters are looking for. You’ll go beyond simple React and learn how to integrate your apps with other prominent technologies like Firebase and Redux.

By the end of this, you’ll have mastered React for professional use and have completed numerous practice projects for your resume.

Happy learning!


Continue reading about React


WRITTEN BYRyan Thelin

Join a community of 500,000 monthly readers. A free, bi-monthly email with a roundup of Educative's top articles and coding tips.