Components and JSX

Understand React component syntax, create and render functional components, and compose them in parent-child relationships.

Learning Goals

At the end of this Tutorial, you will be able to:

  • Create React components using JavaScript functions.
  • Render components to the web browser DOM.
  • Compose React components in parent-child relationships.
  • Understand JSX syntax and how it extends JavaScript to simplify the creation of components in React.

Components in React

Components are the core of React. Components let you split the UI into independent, reusable pieces, and think about each piece in isolation.

React components are the core building blocks of React applications so it's important to become very familiar with writing them.

Functional components

A component created with a JavaScript function is called a stateless functional component. It can receive data and render it, but cannot manage or track changes to that data.

To create a component with a function, you simply write a JavaScript function that returns either JSX or null.

Note that component names are written in PascalCase rather than JavaScript-style camelCase. Below is an example of a stateless functional component that returns some HTML.

function HeaderContent () {
   return (
      <header><h1>Corporate strategy</h1></header>
   )
}

You could then display this component to a container named header in a web page with the React render() method. For example.

header.render(
   <HeaderContent />
);

Rendering HTML content without components

Let's begin by rendering some HTML content in a web page without using components. You will use this as a basis for adding components in the next few exercises.

  1. In VS Code, open the index.html and index.js files. Display the index.html file with Live Server in your web browser.
  2. Into your index.html file, copy-and-paste the two div tags with IDs of header and main as shown below.
    <div id="header"></div>
    <div id="main"></div>
  3. Into your index.js file, copy-and-paste the following two statements that will create variables.
    const header = ReactDOM.createRoot(document.getElementById('header'))
    const main = ReactDOM.createRoot(document.getElementById('main'))
  4. Next, enter these two render() statements.
    header.render(<header><h1>Corporate strategy</h1></header>)
    main.render(<main><section><p>Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition.</p></section></main>)  
  5. Save your two files and verify that the output displays correctly in your browser.

As in the previous Tutorial you are rendering elements from React to the web browser.

Rendering HTML content with components

Let's update the code in Exercise 2.1 to use functional components.

  1. In your index.js file, add the following two render() statements. You will use each one to display a component in a div of your web page.
    header.render(
       <HeaderContent />
    )
    
    main.render(
       <MainContent />
    )
  2. Next, enter the following two JavaScript functions with the return keywords:
    function HeaderContent () {
       return (
       )
    }
    function MainContent () {
       return (
       )
    }
    Note that each function name matches the name of a component. screenshot
  3. Update the first function code block with the element from the first React render() statement at the top of your index.js file.
    function HeaderContent () {
       return (
          <header><h1>Corporate strategy</h1></header>
       )
    }
  4. And update the second function code block with the element from the second React render() statement.
    function MainContent () {
       return (
          <main><section><p>Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition.</p></section></main>
       )
    }
  5. Delete or comment out the two original React render() statements from index.js and save the file. screenshot
  6. Save index.js and verify both components display correctly in your web browser.

Tidying up the component code

Your code from the previous exercise uses two render() statements in React to update two div containers in the HTML file. Let's simplify this.

  1. In index.html, delete or comment out the two current div tags and enter a new one with an ID of root. screenshot
  2. In index.js, delete or comment out the header and main variables at the top of the file, and define a new root variable. screenshot
  3. Also, replace the two render() statements with one that outputs to the root container in the web page. screenshot
  4. Save your work and verify the components display correctly.

React components are compostible

React enables you to 'compose' multiple components together in parent-child relationships.

Imagine you are building an app and have created three components: a Navbar, Dashboard, and Footer.

To compose these components together, you could create an App parent component which renders each of these three components as children. To render a component as a child in a React component, you include the component name written as a custom HTML tag in the JSX. For example, in the render() method you could write:

return (
   <App>
      <Navbar />
      <Dashboard />
      <Footer />
   </App>
)

When React encounters a custom HTML tag that references another component (a component name wrapped in < /> like in this example, it renders the markup for that component in the location of the tag.

Component composition is one of React's powerful features. When you work with React, it is important to start thinking about your user interface in terms of components like the App example in the last challenge. You break down your UI into its basic building blocks, and those pieces become the components. This helps to separate the code responsible for the UI from the code responsible for handling your application logic. It can greatly simplify the development and maintenance of complex projects.

Nesting components

In this next exercise, you will nest a new component inside an existing one. Here are the steps.

  1. In index.js, add a function that will return the content of a new component named ImgContent as follows.
    function ImgContent () {
       return (
          <img src="cafe.jpg" alt="sample image" />
       )
    }
  2. Update the function that returns the content of the MainContent component as shown below.
    function MainContent () {
       return (
          <div>
    	<ImgContent />
             <main><section><p>Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition.</p></section></main>
          </div>
        )
    }
    Your new, updated components should now display correctly.

About JSX

JSX is syntax extension to JavaScript that makes is easier to build UI components with React.

Consider the React statement below.

root.render(
   <h1>Hello, world!</h1>
)

The part within parenthesis () is JSX. It looks like plain HTML that is written inside JavaScript.

JSX can accept variables, written inside curly braces { }. For example:

const firstName = 'John';
root.render(
   <h1>Hello, {firstName}</h1>
)

In fact, you can put any valid JavaScript expression inside the curly braces in JSX. For example, 2 + 2, user.firstName, formatName(user) – even loops and conditional if statements.

However, because JSX is not valid JavaScript, JSX code must be compiled into JavaScript. The transpiler Babel is a popular tool for this process.

Finally, one important thing to know about JSX is that it must return only a single element. This one parent element would wrap all of the other levels of nested elements.