Your Second React Component

By Yeo Yong Kiat in ReactJS

5 min read
What happened to composability? What happened to writing webpages and apps in convenient code components? Why is everything just App.js? Hold your horses boy. We're creating your second component today.

When Do We Create Components?

Before we create our second component, I think we should address the question of when components should be created. Because, sure, we could create a component for every single HTML element - every Tom, Dick, Harry element out there - but that just brings us right back to HTML, doesn't it?

The principles are easy, and actually resonates with the same principles in general coding. We write up a component whenever our tasks become too repetitive or too complicated, either operationally or visually. Another good reason is when we think a certain chunk of code does something specialised enough for it to be compartmentalised as a standalone. Or maybe when something seems re-useable. In fact, these are the very reasons why you choose to code a module and develop your own packages.

Extracting a Function Into a Component

Let's go back to our App.js component - recall that there was a section of code where we generated three bullet points via a map function? Let's try to rewrite that section by lifting it up as a separate function before the App function.

import React from 'react';
import {v4 as uuidv4} from 'uuid';

const data = {
    title: "Best App",
    contents: "That's right baby!",
    bulletItems: [
                  {name: "Item 1",
                   id: uuidv4()},
                  {name: "Item 2",
                   id: uuidv4()},
                  {name: "Item 3",
                   id: uuidv4()}
                  ]
};

// Let's lift up the bullet generation
// into a function here
function Bullet() {
    return (
        <ul>
            {data.bulletItems.map( (item) => {
                return (
                    <li key={item.id}>
                    {item.name}
                    </li>)
            })}
        </ul>
    );
};

// We then reference the Bullet function here
function App() {
  return (
    <div className="appContainer">
      <h1>{data.title}</h1>
      <p>{data.contents}</p>      
      <Bullet />
    </div>
  );
};

export default App;

And if you've done it right, your webpage still remains the same:

Best App

That's right baby!

  • Item 1
  • Item 2
  • Item 3

Hard to believe it, but you've written your second React component! That snippet of code making up the Bullet() function is a React component. With the React syntax, you can now reference this Bullet() function as a <Bullet /> tag within the JSX syntax. Just take note how all components are named in UpperCamelCase notation.

Extracting Components as Modules

Now that you've written your second React component, the next step is to modularise it by extracting the code into a separate JS file, and then importing that code in your App.js file. Confused? Let's do it step by step - so copy out the Bullet() function and save it as another file called Bullet.js:

// Save this as Bullet.js 
// in the same directory as App.js

// You need this line for JSX to work
import React from 'react';

const data = {
  title: "Best App",
  contents: "That's right baby!",
  bulletItems: [
                {name: "Item 1",
                 id: uuidv4()},
                {name: "Item 2",
                 id: uuidv4()},
                {name: "Item 3",
                 id: uuidv4()}
                ]
};

// Cut out the Bullet() function from App.js
function Bullet() {
    return (
        <ul>
            {data.bulletItems.map( (item) => {
                return (
                    <li key={item.id}>
                    {item.name}
                    </li>)
            })}
        </ul>
    )
}

// You need this line
export default Bullet

Go back to App.js and import Bullet as a React component:

import React from 'react';
import {v4 as uuidv4} from 'uuid';

// Import Bullet.js
import Bullet from './Bullet';

const data = {
    title: "Best App",
    contents: "That's right baby!",
    bulletItems: [
                  {name: "Item 1",
                   id: uuidv4()},
                  {name: "Item 2",
                   id: uuidv4()},
                  {name: "Item 3",
                   id: uuidv4()}
                  ]
};

function App() {
  return (
    <div className="appContainer">
      <h1>{data.title}</h1>
      <p>{data.contents}</p>      
      <Bullet />
    </div>
  );
};

export default App;

Immediately, your code is much neater! You've successfully modularised part of your HTML content as a React component, and then called that component into App.js to render 3 bullet points in your web page.

Before we end this article, some of you may have noticed that we had some redundancy: we actually defined "data" twice! Once in App.js and again in Bullet.js. Surely we only need to define it once? Indeed, the React way is to define the state (and all functions) once in the parent container (i.e. App.js) and to then pass it down as "props" (which stands for "properties") to the children components. We'll look at how to do this in future posts.

Next up, we see how to insert event handler functions into HTML elements via React.

Find more ReactJS stories on my blog. Have a suggestion? Contact me at [email protected].