React Daily UI - 006 Profile Page

Sophia Shoemaker

Jack Oliver

January 11, 2017 // 14 min read

This post is a part of the React Daily UI post series, a joint effort between Jack Oliver, Sophia Shoemaker, and the rest of the team at Fullstack React. Each day we're explaining in detail how to create a UI component with React.

You can view the Codepen implementation here

Or you view the code on Github here

Welcome to React Daily UI, where we go 100 days building 100 beautiful React applications. We're really excited to be partnering with Jack Oliver who is embarking on this ambitious project with us.

Jack is designing and writing the code for these applications and we're going to deconstruct each one to highlight the features that are unique to React.

Today we're going to create a profile page:

Overview

This profile page has a few components that are generated using the createClass method available in React. Today we are going to learn how to convert these components into functional and class components. We have three different components that we are going to convert:

  • An Image component
  • A Profile component
  • An App component

We will convert the first two components to functional components and the App component to a class component.

Table of Contents

Functional Components

Functional components are the simplest (and most performant) types of components. They are just a JavaScript function that receive props as a parameter. Functional components do not have state or a this object. When mounted, they receive data from their parent component and display the data.

Functional components are akin to React components that only implement the render() method. For components that only have a view, functional components are the way to go.

Our profile page has two components that we are going to convert to functional components: the Image component and the Profile component.

Converting the Image component

Our original Image component looks like this:


var Image = React.createClass({
  render: function() {
    return (
      <div className="Image" style={{backgroundImage: 'url(' + this.props.src + ')'}}></div>
    );
  }
});

To convert our Image component, we are going to do 3 things:

  1. Create a new function that has the same name as our Image component:

function Image(props){

  1. Take the return value from our render method in our original component and make that the return value of our function.

return (
  <div className="Image" style={{backgroundImage: 'url(' + this.props.src + ')'}}></div>
);

  1. If we have any props in our component, we need to remove the this keyword, since the props are passed in as a parameter to the function. In our Image component, we change this.props.src to props.src

Here is what our newly created Image component looks like now:


function Image(props){
    return (
      <div className="Image" style={{backgroundImage: 'url(' + props.src + ')'}}></div>
    ); 
}

Converting the Profile component

Following the same procedure above, let's convert our Profile component convert it to a functional component.

  1. Create a function called Profile and give it props as an argument.

function Profile(props){

  1. Take the return value from our render method and make that the return value of our function.

<div className="Profile">
  <h1 className="Name">{this.props.person.name}</h1>
  <p className="Bio">{this.props.person.biography}</p>
  <div className="Quote">
    <blockquote>&ldquo; {this.props.quote.content} &rdquo;</blockquote>
    <div className="byline">&mdash; {this.props.quote.source}</div>
  </div>
  
</div>

  1. We change any references to this.props to props. In our Profile component we need to change this.props to props in multiple places:

  2. this.props.person.name to props.person.name

  3. this.props.person.biography to props.person.biography

  4. this.props.quote.content to props.quote.content

  5. this.props.quote.source to props.quote.source

Here is what our newly created Profile function component looks like:


function Profile(props){
  return (
      <div className="Profile">
        <h1 className="Name">{props.person.name}</h1>
        <p className="Bio">{props.person.biography}</p>
        <div className="Quote">
          <blockquote>&ldquo; {props.quote.content} &rdquo;</blockquote>
          <div className="byline">&mdash; {props.quote.source}</div>
        </div>
        
      </div>
    );
}

Class components

Our App component is a litle more complicated in terms of functionality, so we are going to convert the component to a JavaScript class.

The JavaScript syntax for classes are new-ish as of the ES6 (also known as ES2015/ECMAScript 6/ECMAScript2015) specifications. Classes are not unique to JavaScript. Classes are a common construct used in many languages, but the "under the hood" implementation details of using the class keyword is different in JavaScript compared to other class-based languages, like Java or C++.

What is a class?

In the real world, there are many types of objects, all with specific functions and features. For example, a bicycle is a commonly used object that has 2 wheels, gears, handlebars, brakes and a seat. These are all common properties of a bicycle. While riding a bicycle, you might apply the brakes, shift gears or pedal. Creating a bicycle requires a blueprint to make sure it is built properly, to the correct specifications.

In the programming world, we also make use of "blueprints" or "templates" to build objects. These templates are called classes, and they specify the certain actions (more commonly known as methods) and properties an object has. When we create a new object using a class, we say we are "instantiating an object." We'll often refer to this object as an instance of the class.

When we create components in React, we typically extend the Component class or "template". The Component class React gives us has methods associated with it (like the setState method) that the components we create can use in our subclassed objects.

Objects, classes and prototypes are a fairly complex, but important topic to learn in JavaScript. If you'd like to go more in depth, these blog posts are highly recommended for learning more:

"Understanding Prototypes in JavaScript" by Yehuda Katz

"How to Use Classes and Sleep at Night" by Dan Abramov

"What’s the Difference Between Class & Prototypal Inheritance?" by Eric Elliott

Converting the App component

To convert our App component, we need to do a few things.

  1. First, we import the Component class from React using this syntax:

mport React, { Component } from 'react';

  1. Next, we change our code from using React.createClass to using the JavaScript class syntax:

The first line of our old App component looks like this:


var App = React.createClass({

We need to remove the React.creacteClass function call and replace it with the class keyword. We also need to extend the Component class:


class App extends Component{

  1. Then, we create a constructor function and pass in props so that our component has access to any props passed into it.

constructor(props) {

Inside our constructor function we must first call super(props) in this syntax. Calling super() calls the React.Component constructor function. In derived classes, super() must be called before we can use this. Leaving super() out will cause a reference error.


super(props);

  1. Next, we need to initialize the state of our component. Instead of using the getInitialState function, we will initialize the state of our component in our constructor function. We can take the object returned from our getInitialState function and assign it to this.state in our constructor:

this.state = {
  person: {
    name: 'Jack-Edward Oliver',
    biography: '26 year old Designer / Developer living in Stockholm. Originally from Oxford, England. Love to make stuff.',
  },
  image: 'http://static1.squarespace.com/static/55acc005e4b098e615cd80e2/t/57b057398419c2c454f09924/1471025851733/',
  quote: {
    content: 'Beautiful things don\'t ask for attention',
    source: 'The Secret Life of Walter Mitty'
  }
  

  1. Finally, we'll need to change the syntax of our render function slightly to look like this:

render() {
  return(
    <div className="App">
      <Image src={this.state.image} />
      <Profile person={this.state.person} quote={this.state.quote} />
    </div>
  );
}

Here is the full result of our new App component:


class App extends Component{
  constructor(props) {
    super(props);
    this.state = {
      person: {
        name: 'Jack-Edward Oliver',
        biography: '26 year old Designer / Developer living in Stockholm. Originally from Oxford, England. Love to make stuff.',
      },
      image: 'http://static1.squarespace.com/static/55acc005e4b098e615cd80e2/t/57b057398419c2c454f09924/1471025851733/',
      quote: {
        content: 'Beautiful things don\'t ask for attention',
        source: 'The Secret Life of Walter Mitty'
      }
      
    };
  }
  render() {
    return(
      <div className="App">
        <Image src={this.state.image} />
        <Profile person={this.state.person} quote={this.state.quote} />
      </div>
    );
  }
}

Try it out!

Check out the Codepen example:

The complete source for this article is also available on Github here.

To start the app, download the code, cd into the project directory and type:

   npm install
   npm start

Learn React the right way

The up-to-date, in-depth, complete guide to React and friends.

Download the first chapter

Sophia Shoemaker

Sophia Shoemaker became addicted to React in 2014. She is a full stack developer but React is her technology of choice. She loves working on her pet project Shop Sifter and editing the Fullstack React Newsletter.

Recently, she became a mentor at Hackbright Academy and is excited to encourage and empower women looking to get involved in programming. When she isn't cobbling code, she can be found flying in her husband's Beechcraft Bonanza and playing with her 2 kids.

Connect with Sophia on Twitter at @wisecobbler.

Jack Oliver

Hi, I'm Jack! I'm a Developer & Designer living in Stockholm, Sweden. I've worked with super cool people; from Mercedes-Benz, Farfetch, NotOnTheHighStreet, and Mimecast, and am currently building cool stuff at Observify. Part-time photographer, full-time joker. I'm currently doing 100 days of React on Codepen check it out here.

Connect with me on twitter @mrjackolai.