Understanding React Components (Part 1): Working with Functional Components

What are Components?

Components are the building blocks of any React application. They can be though of as  customized and reusable HTML elements that can be used independently and/or together with other components in unique and clever ways to created interactive and dynamic user interfaces. A component is used to describe what should appear on the screen. Once declared it can be reused as needed, it can be rendered alongside other components, it can be rendered inside other components, and it can contain other components.

What Are Functional Components?

React’s functional components are called so because they are literally functions. A functional component is declared as a JavaScript function that optionally takes in an input called “props”, and returns a description of what should appear on the user interface. A simple example of a functional component that returns “Hello World” is given below.

const Hello = ()=>{
    return(
        <h1>Hello World </h1>
    )
}

The above functional component is defined as an ES6 arrow function. It does not take any props, and only outputs “Hello World” on the user interface.

Hello World
Hello world

However, data can be passed into a component as props, and then used to describe the components out to the screen. For example, to create a component that says “Hello” to a given username, we can create a functional component that takes in the username as props. This can be shown in the code below.

const Hello = (props)=>{
    return(
        <h1>Hello {props.username} </h1>
    )
}

ReactDOM.render(
    <Hello username="Lance"/>,
    document.getElementById("root")
)
Hello Lance
Hello Lance

Returning a Single Parent Element

One thing to note is that React expects only one parent element to be returned by a component, therefore having a component that returns, for example, two “Hello World” statements in <h1> tags as shown below is going to produce an error.

const Hello = (props) => {
    return(
        <h1>Hello World </h1>
        <h1>Hello {props.username} </h1>
    )
}

One way to address this issue is by wrapping all the elements you want to return within a single <div> tag. This way the <div> becomes your one parent element.

const Hello = (props) => {
    return(
        <div>
            <h1>Hello World </h1>
            <h1>Hello {props.username} </h1>
        </div>
    )
}

Working with Functional Components

Let us create a simple React app that displays brief profiles of football players stored in an array of objects. You can start by cloning the starter React project for this tutorial. It contains a single file, index.html, which imports all the required tools for React to run, additional styling, an imported font, and an array called “profiles” that stores player profile objects.

Next, beneath the “profiles” array, let us define a component called “ProfileDisplayer” that displays a single player profile. This component should take as props a single player profile object from the “profiles” array and return JSX for displaying all the information available in that profile such as name, age, nationality and position.

const ProfileDisplayer = (props) => {
    return(
        <div className="profile">
            <h2>{props.profile.name}</h2>
            <h3>Age: {props.profile.age}</h3>
            <h3>Nationality: {props.profile.nationality}</h3>
            <h3>Club: {props.profile.club}</h3>
            <h3>Position: {props.profile.position}</h3>
        </div>
    )
}

The CSS class “profile” defined in the head section of the HTML file is used to style the parent <div> returned by the component. And the custom styled <h2> and <h3> tags are used to display the profile information.

Now that we have the “ProfileDisplayer” component created, we can render a single player profile in our app.

ReactDOM.render(
    <ProfileDisplayer profile={profiles[0]}/>,
    document.getElementById("root")
)
Profile of one player
Profile of one player

Works great!!! However we don’t want to display just one profile, but all the profiles in the “profiles” array. To do that we will start by creating another functional component called “ProfilesContainer” which will act as a container for all player profiles. “ProfilesContainer” will take in the whole “profiles” array as props, use the Array.prototype.map() method to loop through the array and return a new array of “ProfileDIsplayer” components for all the player profiles. We will also use this container to give our page a heading, therefore immediately after returning the opening <div> and before beginning to map through our array, we will display our page heading using <h1>Profiles of Top Football Players</h1>.

const ProfilesContainer = (props) => {
    return(
        <div>
            <h1>Profiles of Top Football Players</h1>
            {props.profiles.map(item=>(
                <ProfileDisplayer profile = {item} key={item.id} />
            ))}
        </div>
    )
}

ReactDOM.render(
    <ProfilesContainer profiles={profiles}/>,
    document.getElementById("root")
)
all profiles
Profiles of all players

It should be noted that React expects each element rendered from an array to have a unique key. Fortunately, all profile objects in our “profiles” array have a unique “id” attribute, therefore we can assign each profile’s “id” as its “ProfileDisplayer” component key.

This simple example shows how components can be reused to display similar data, as well as how components can be composed to form more complex components. The complete project code can be found here, and the application can be viewed here.

In our next tutorial we’ll be looking at a different way of defining components using ES6 classes, and the trade-offs between using functional and class components in React.

1
0

Related Posts