Functional Components

July 20, 2017


React Components

A React Component is an independent reusable component that outputs a React Element based on its properties and state.

There are two types of React Components:

  • Functional Components
  • Class Components

Class Components have state, lifecycle methods, and properties while Functional Components only have properties.

Functional Components

Functional Components are just functions that output React Elements. By convention, the first letter of the function name should be capitalized.

Here is an example:

    function HelloWorld(){
        return <h1>Hello World!</h1>
    }

You can use the React Component in JSX by creating an HTML tag with the same name as the React Component:

    var element = <HelloWorld/>

Another Example:

    
   ReactDOM.render(
        <HelloWorld/>,
        document.querySelector("#root")
    )

These examples will all evaluate to the React Element that is returned by the HelloWorld Component.

Adding Properties to Functional Components

The first argument to a Functional Component is an object that contains the component’s properties.

    function HelloWorld(props){
        return <h1>Message: {props.message}</h1>
    }

You can supply property values the same way as you supply attribute values:

   ReactDOM.render(
        <HelloWorld message="Hello World!"/>,
        document.getElementById("root")
    )

Properties can be string literals, arrays or any other type of JavaScript object including other React Elements:

    function HelloWorld(props){
        return <h1>Value: {props.numberArray[props.index]} </h1>
    }

    ReactDOM.render(
        <HelloWorld index = "3" numberArray={[1,2,3,4,5]}/>,
        document.querySelector("#root")
    )

You can supply as many property values as you want and they will all be accessible through the props argument.

Composition

Composing Components

Functional Components can include other Functional Components in their output. This lets us keep our components organized and readible.

For example, look at this Shopping Application that makes use of Composition:

    function ShoppingTitle(props){
        return (
            <div>
                <h1>{props.title}</h1>
                <h2>Total Number of Items: {props.numItems}</h2>
            </div>

        ) 
    }
    function ListItem(props){
        return <li>{props.item}</li>
    }

    function ShoppingList(props){
        return (
            <div>
                <h3>{props.header}</h3>
                <ol>
                    <ListItem item = {props.items[0]}/>
                    <ListItem item = {props.items[1]}/>
                    <ListItem item = {props.items[2]}/>
                </ol>
            </div>
        )
    }


    function ShoppingApp(props){

        return (
            <div>
                <ShoppingTitle title = "My Shopping List" numItems = "9"/>
                <ShoppingList header = "Food" items = {[ "Apple","Bread","Cheese"]}/>
                <ShoppingList header = "Clothes" items = {[ "Shirt","Pants","Hat"]}/>
                <ShoppingList header = "Supplies" items = {[ "Pen","Paper","Glue"]}/>
            </div>
        )
    }

    ReactDOM.render(
        <ShoppingApp/>,
        document.getElementById("root")
    )

Compare that to just defining all the UI in one Functional Component.

    function ShoppingApp(props){
        return (
            <div>
                <div>
                    <h1>My Shopping List</h1>
                    <h2>Total Number of Items: 9</h2>
                </div>
                <div>
                    <h3>Food</h3>
                    <ol>
                        <li>Apple</li>
                        <li>Bread</li>
                        <li>Cheese</li>
                    </ol>
                </div>
                <div>
                    <h3>Clothes</h3>
                    <ol>
                        <li>Shirt</li>
                        <li>Pants</li>
                        <li>Hat</li>
                    </ol>
                </div>
                <div>
                    <h3>Supplies</h3>
                    <ol>
                        <li>Pen</li>
                        <li>Paper</li>
                        <li>Glue</li>
                    </ol>
                </div>
            </div>
        )
    }

    ReactDOM.render(
        <ShoppingApp/>,
        document.getElementById("root")
    )

Conditional Rendering

Conditional Rendering

The output of a Functional Component can be determined based on its properties.

For example:

    function Feature(props){
        if (props.active == true){
            return <h1>This feature is active</h1>
        }
        else{
            return <h1>This feature is not active</h1>
        }

    }

This can also be accomplished using an inline conditional operator:

    function Feature(props){
        return <h1>This feature is {props.active? "active" : "not active"}</h1>
    }
Preventing Rendering

The output of a Functional Component can be prevented from rendering.

For example:

    function Feature(props){
        if(props.active!){
            return null
        }
        else{
            return <h1>{props.message}</h1>
        }
    }

You can also conditionally prevent a feature from rendering using the && operator:

    function Feature(props){
        return (
            props.active && <h1>{props.message}</h1>
        )
    }

With the && operator, true and expression will always evaluate to expression. On the other hand, false and expression will always evaluate to false which won’t render.

Module 1 Tutorial

This tutorial is attended to teach you how to model an HTML DOM using React Components.

Step 1: Break up the UI into components

The first step is to identify parts of the UI that can be broken into their own components.

As the above image shows, we have broken up the application into several sections:

  • A component that contains a title and description of the shopping application (blue)
  • A component that contains a header a list of three items (red)
  • A component that represents a list items (dark red)
Step 2: Creating the individual React Components

To start off, we will create a React Component that represents an individual list item. For now, we will return a <li> tag with a test string, but later on we will replace it with an attribute passed from the component’s properties.

    function ListItem(props){
        return <li>Test String</li>
    }

We can test the component by rendering it to the page, be sure to add a root div in the HTML page:

   
    ReactDOM.render(
        <ListItem/>,
        document.querySelector("#root01")
    )

Next will create a React Component that contains the application’s title and description. For now, we will return <h1> and <h2> tags that contain test strings, but later on we will replace them with attributes passed from the component’s properties. We must wrap the headers with <div> tag to ensure that there is one element that encompasses all of the returned React Elements. In addition, we must surround the returned value with parenthesis since the return value spans several lines.

    function ShoppingTitle(props){
        return (
            <div>
                <h1>Test Title</h1>
                <h2>Test Description</h2>
            </div>

        ) 
    }

We can test the component by rendering it to the page:

    ReactDOM.render(
        <ShoppingTitle/>,
        document.querySelector("#root02")
    )

Lastly, we will create the component that contains a header and three ListItem components. For now, we will return a <h3> tag with a test string, but later on we will replace it with an attribute passed from the component’s properties. We must wrap the headers with <div> tag to ensure that there is one element that encompasses all of the returned React Elements. In addition, we must surround the returned value with parenthesis since the return value spans several lines.

    function ShoppingList(props){
        return (
            <div>
                <h3>Test Header</h3>
                <ol>
                    <ListItem/>
                    <ListItem/>
                    <ListItem/>
                </ol>
            </div>
        )
    }

We can test the component by rendering it to the page:

    ReactDOM.render(
        <ShoppingList/>,
        document.querySelector("#root03")
    )
Step 3: Putting the components together

Now that we have created and tested the individual React Components, we will now encompass them under one React Component. The ShoppingApp component will contain the ShoppingTitle component and three ShoppingList components.

    function ShoppingApp(props){

        return (
            <div>
                <ShoppingTitle/>
                <ShoppingList/>
                <ShoppingList/>
                <ShoppingList/>
            </div>
        )
    }

We can test the application by rendering it to the page:

    ReactDOM.render(
        <ShoppingApp/>,
        document.getElementById("root04")
    )
Step 4: Adding in the application data

Now that we have our entire application modeled using React Components, we can now replace our test strings with the actual application data.

    function ShoppingApp(props){

        return (
            <div>
                <ShoppingTitle title = "My Shopping List" numItems = "9"/>
                <ShoppingList header = "Food" items = {[ "Apple","Bread","Cheese"]}/>
                <ShoppingList header = "Clothes" items = {[ "Shirt","Pants","Hat"]}/>
                <ShoppingList header = "Supplies" items = {[ "Pen","Paper","Glue"]}/>
            </div>
        )
    }

In the ShoppingApp component, I have added several attributes that contain the application data. I have supplied an array of strings to the items attribute of the ShoppingList component. The items in the array will be passed down to the individual ListItem components within the ShoppingList component. The numItems attribute on the ShoppingTitle component represents the number of total items in all of the shopping lists. This value will be included in the second header of the ShoppingApp component.

Now we must edit the ShoppingList component to make use of the supplied data. The shopping list headers can be accessed through props.header and the shopping items can be accessed from their indices from the props.items array.

    function ShoppingList(props){
        return (
            <div>
                <h3>{props.header}</h3>
                <ol>
                    <ListItem item = {props.items[0]}/>
                    <ListItem item = {props.items[1]}/>
                    <ListItem item = {props.items[2]}/>
                </ol>
            </div>
        )
    }

Next, we must edit the ShoppingTitle component to make use of the supplied data. The title and number of items can be accessed through props.title and props.numItems respectively.

    function ShoppingTitle(props){
        return (
            <div>
                <h1>{props.title}</h1>
                <h2>Total Number of Items: {props.numItems}</h2>
            </div>

        ) 
    }

Lastly, we must edit the ListItem component to make use of the supplied data. The item name can be accessed through the props.item.

    function ListItem(props){
        return <li>{props.item}</li>
    }

Now that we have completed all of the steps, we can test our entire application by rendering it to the page:

    ReactDOM.render(
        <ShoppingApp/>,
        document.querySelector("root05")
    )