Advanced Topics

In this unit, you will learn a variety of useful techniques that React programmers are expected to know.

You’ll learn how to make a stateless functional component, how to make a propType, how to write a form, and how to use styles.

You’ll also be introduced to your second programming pattern: dividing components into presentational components and container components.

Inline Styles

There are many different ways to use styles in React. This lesson is focused on one of them: inline styles.

An inline style is a style that’s written as an attribute, like this:

<h1 style={{ color: ‘red’ }}>Hello world</h1>

 

Notice the double curly braces. What are those for?

The outer curly braces inject JavaScript into JSX. They say, “everything between us should be read as JavaScript, not JSX.”

The inner curly braces create a JavaScript object literal. They make this a valid JavaScript object:

{ color: ‘red’ }

 

If you inject an object literal into JSX, and your entire injection is only that object literal, then you will end up with double curly braces. There’s nothing unusual about how they work, but they look funny and can be confusing.

Make a Style Object Variable

That’s all that you need to apply basic styles in React! Simple and straightforward.

One problem with this approach is that it becomes obnoxious if you want to use more than just a few styles. An alternative that’s often nicer is to store a style object in a variable, and then inject that variable into JSX.

Look in the code below. The style object is defined on lines 3-6, and then injected on line 11.

import React from ‘react’;

const styles = {
  color: ‘darkcyan’,
  background: ‘mintcream’
};

export class StyledClass extends React.Component {
  render() {
    return (
      <h1 style={styles}>
        Hello world
      </h1>
    );
  }
}

 

If you aren’t used to using modules, then this code may have made you twitch uncontrollably:

const style = {
  color: ‘darkcyan’,
  background: ‘mintcream’
};

 

Defining a variable named style in the top-level scope would be an extremely bad idea in many JavaScript environments! In React, however, it’s totally fine.

Remember that every file is invisible to every other file, except for what you choose to expose via module.exports. You could have 100 different files, all with global variables named style, and there could be no conflicts.

 

Style Name Syntax

In regular JavaScript, style names are written in hyphenated-lowercase:

const styles = {
  ‘margin-top’:       “20px”,
  ‘background-color’: “green”
};

 

In React, those same names are instead written in camelCase:

const styles = {
  marginTop:       “20px”,
  backgroundColor: “green”
};

 

This has zero effect on style property values, only on style property names.

 

Style Value Syntax

You learned how style names are slightly different in React than they are in regular JavaScript. It is time to learn how style values are slightly different in React than they are in regular JavaScript.

In regular JS, style values are almost always strings. Even if a style value is numeric, you usually have to write it as a string so that you can specify a unit. For example, you have to write “450px” or “20%”.

In React, if you write a style value as a number, then the unit “px” is assumed.

How convenient! If you want a font size of 30px, you can write:

{ fontSize: 30 }

 

If you want to use units other than “px,” you can use a string:

{ fontSize: “2em” }

 

Specifying “px” with a string will still work, although it’s redundant.

A few specific styles will not automatically fill in the “px” for you. These are styles where you aren’t likely to use “px” anyway, so you don’t really have to worry about it. Here is a list of styles that don’t assume “px”.

 

Share Styles Across Multiple Components

What if you want to reuse styles for several different components?

One way to make styles reusable is to keep them in a separate JavaScript file. This file should export the styles that you want to reuse, via export. You can then import your styles into any component that wants them.

 

PropTypes

In this section, you will learn to use an important React feature called propTypes.

propTypes are useful for two reasons. The first reason is prop validation.

Validation can ensure that your props are doing what they’re supposed to be doing. If props are missing, or if they’re present but they aren’t what you’re expecting, then a warning will print in the console.

This is useful, but reason #2 is arguably more useful: documentation.

Documenting props makes it easier to glance at a file and quickly understand the component class inside. When you have a lot of files, and you will, this can be a huge benefit.

Apply PropTypes

Take a look at MessageDisplayer‘s render function.

import React from ‘react’;

import PropTypes from ‘prop-types’;


export class MessageDisplayer extends React.Component {
  render() {
    return <h1>{this.props.message}</h1>;
  }
}

// This propTypes object should have
// one property for each expected prop:
MessageDisplayer.propTypes = {
  message:PropTypes.string
};

 

Notice the expression this.props.message. From this expression, you can deduce that MessageDisplayer expects to get passed a prop named message. Somewhere, at some time, this code is expected to execute:

<MessageDisplayer message=“something” />

 

If a component class expects a prop, then you can give that component class a propType!

The first step to making a propType is to search for a property named propTypes on the instructions object. If there isn’t one, make one! You will have to declare it after the close of your component declaration, since it will be a static property.

See the example of a propTypes property on lines 11-13. Notice that the value of propTypes is an object, not a function!

The second step is to add a property to the propTypes object. For each prop that your component class expects to receive, there can be one property on your propTypes object.

MessageDisplayer only expects one prop: message. Therefore, its propTypes object only has one property.

Add Properties to PropTypes

Look at the property on MessageDisplayer‘s propTypes object:

message: React.PropTypes.string

 

What are the properties on propTypes supposed to be, exactly?

The name of each property in propTypes should be the name of an expected prop. In our case, MessageDisplayer expects a prop named message, so our property’s name is message.

The value of each property in propTypes should fit this pattern:

PropTypes.expected-data-type-goes-here

 

Since message is presumably going to be a string, we chose React.PropTypes.string. You can see this on line 12. Notice the difference in capitalization between the propTypes object and React.PropTypes!

Each property on the propTypes object is called a propType.

Check Runner.js. Find Runner‘s propTypesobject.

import React from ‘react’;

import PropTypes from ‘prop-types’;

export class Runner extends React.Component {
  render() {
  let miles = this.props.miles;
    let km = this.props.milesToKM(miles);
    let races = this.props.races.map(function(race, i){
      return <li key={race + i}>{race}</li>;
    });

    return (
      <div style={this.props.style}>
        <h1>{this.props.message}</h1>
        { this.props.isMetric &&
          <h2>One Time I Ran {km} Kilometers!</h2> }
        { !this.props.isMetric &&
          <h2>One Time I Ran {miles} Miles!</h2> }
        <h3>Races I’ve Run</h3>
        <ul id=“races”>{races}</ul>
      </div>
    );
  }
}

Runner.propTypes = {
  message:  PropTypes.string.isRequired,
  style:    PropTypes.object.isRequired,
  isMetric: PropTypes.bool.isRequired,
  miles:    PropTypes.number.isRequired,
  milesToKM:PropTypes.func.isRequired,
  races:    PropTypes.array.isRequired
};

 

Runner has six propTypes! Look at each one. Note that bool and func are abbreviated, but all other data types are spelled normally.

If you add .isRequired to a propType, then you will get a console warning if that prop isn’t sent.

Try to find all six props from the propTypes object in Runner‘s render function: this.props.message, this.props.style, etc.

PropTypes in Stateless Functional Components

Remember stateless functional components? You can see some familiar ones in Example.js.

How could you write propTypes for a stateless functional component?

// Usual way:
class Example extends React.component{
}
Example.propTypes = {

};


// Stateless functional component way:
const Example = (props) => {
  // ummm ??????

 

It turns out the process is fairly similar. To write propTypes for a stateless functional component, you define a propTypes object as a property of the stateless functional component itself. Here’s what that looks like:

const Example = (props) => {
  return <h1>{props.message}</h1>;
}

Example.propTypes = {
  message: React.PropTypes.string.isRequired
};

 

Separating presentational components from display components

In this section, you will learn your second programming pattern: separating presentational components from display components.

Check this code:

import React from ‘react’;

import ReactDOM from ‘react-dom’;

const IMAGEPATHS = [
‘https://s3-us-west-2.amazonaws.com/s.cdpn.io/210284/93.jpg’,

 ‘https://s3-us-west-2.amazonaws.com/s.cdpn.io/210284/46.jpg’,

 ‘https://s3-us-west-2.amazonaws.com/s.cdpn.io/210284/59.jpg’
];

export class Users extends React.Component {
  constructor(props) {
    super(props);

    this.state = { currentUser: 0 };

    this.interval = null;

    this.nextUser = this.nextUser.bind(this);
  }

  nextUser() {
    let current = this.state.currentUser;
    let next = ++current % IMAGEPATHS.length;
    this.setState({ currentUser: next });
  }

  componentDidMount() {
    this.interval = setInterval(this.nextUser, 5000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    let src = IMAGEPATHS[this.state.currentUser];
    return (
      <div>
        <h1>Users</h1>
        <img src={src} />
      </div>
    );
  }
}

ReactDOM.render(
  <Users />,
  document.getElementById(‘app’)
);

 

<Users />‘s job is to render a photo carousel of users. It does this perfectly well! And yet, it has a problem: it does too much stuff.

We can break <Users /> into smaller components, but before we do: how do we know that Users does too much stuff? How can you tell when a component has too many responsibilities?

Separating container components from presentational components helps to answer that question. It shows you when it might be a good time to divide a component into smaller components. It also shows you how to perform that division.

 

Here’s the basic idea behind it: if a component has to have state, make calculations based on props, or manage any other complex logic, then that component shouldn’t also have to render HTML-like JSX.

Instead of rendering HTML-like JSX, the component should render another component. It should be that component’s job to render HTML-like JSX.

Following this pattern separates your business logic from your presentational logic, which is a Good Thing.

 

import React from ‘react’;

export class Users extends React.Component {
  render() {
    const src = this.props.src;
    return (
      <div>
        <h1>Users</h1>
        <img src={src} />
      </div>
    );
  }
}

 

Stateless Functional Components

If you have a component class with nothing but a render function, then you can rewrite that component class in a very different way. Instead of using React.Component, you can write it as a JavaScript function!

A component class written as a function is called a stateless functional component. Stateless functional components have some advantages over typical component classes. We’ll cover those advantages in this lesson.

Look at this code to see a stateless functional component in action.

// A component class written in the usual way:
export class MyComponentClass extends React.Component {
  render() {
    return <h1>Hello world</h1>;
  }
}

// The same component class, written as a stateless functional component:
export const MyComponentClass = () => {
  return <h1>Hello world</h1>;
}

// Works the same either way:
ReactDOM.render(
<MyComponentClass />,
document.getElementById(‘app’)
);

 

Adding Props

Stateless functional components usually have props passed to them.

To access these props, give your stateless functional component a parameter. This parameter will automatically be equal to the component’s props object.

It’s customary to name this parameter props. Read this code to see how it works.

// Normal way to display a prop:
export class MyComponentClass extends React.Component {
  render() {
    return <h1>{this.props.title}</h1>;
  }
}

// Stateless functional component way to display a prop:
export const MyComponentClass = (props) => {
  return <h1>{props.title}</h1>;
}

// Normal way to display a prop using a variable:
export class MyComponentClass extends React.component {
  render() {
  let title = this.props.title;
    return <h1>{title}</h1>;
  }
}

// Stateless functional component way to display a prop using a variable:
export const MyComponentClass = (props) => {
let title = props.title;
  return <h1>{title}</h1>;
}

 

Not only are stateless functional components more concise, but they will subtly influence how you think about components in a positive way. They emphasize the fact that components are basically functions! A component takes two optional inputs, props and state, and outputs HTML and/or other components.

You’ll be seeing a lot of stateless functional components in the next React course!

 

Review

In this lesson you have learned:

  • Inline Styles
  • PropTypes
  • Stateless Functional Components

That’s it. You have learn react and ready to make fantastic web application with react.