React applications are made of components.
What’s a component?
A component is a small, reusable chunk of code that is responsible for one job. That job is often to render some HTML and re-render it when some data changes.
Take a look at the code below. This code will create and render a new React component:
import React from 'react';
import ReactDOM from 'react-dom/client';
function MyComponent() {
return <h1>Hello world</h1>;
}
ReactDOM.createRoot(
document.getElementById('app')
).render(<MyComponent />);
Import React
This creates an object named React, which contains methods necessary to use the React library. React is imported from the 'react' package, which should be installed in your project as a dependency. With the object, we can start utilizing features of the react library!
By importing the library, we can use important features such as Hooks, which we’ll explore in detail later.
import React from 'react';
Import ReactDOM
Another import we need in addition to React is ReactDOM
import ReactDOM from 'react-dom/client';
The methods imported from 'react-dom' interact with the DOM.
The methods imported from 'react' do not deal with the DOM at all. They don’t engage directly with anything that isn’t part of React.
To clarify: the DOM is used in React applications, but it isn’t part of React. After all, the DOM is also used in countless non-React applications. Methods imported from 'react' are only for pure React purposes, such as creating components or writing JSX elements.
Create a Function Component
You’ve learned that a React component is a small, reusable chunk of code that is responsible for one job, which often involves rendering HTML and re-rendering it whenever some data changes.
It’s useful to think of components as smaller pieces of our interface. Combined, they are the building blocks that make up a React application. In a website, we can create a component for the search bar, another component for the navigation bar, and another component for the dashboard content itself.
Here’s another fact about components: we can use JavaScript functions to define a new React component. This is called a function component.
In the past, React components were defined using Javascript classes. But since the introduction of Hooks (something we’ll discuss later), function components have become the standard in modern React applications.
After we define our functional component, we can use it to create as many instances of that component as we want.
Let’s take a look at the example from the first exercise:
import React from 'react';
function MyComponent() {
return <h1>Hello, I'm a functional React Component!</h1>;
}
export default MyComponent;
On the third line, a function is defined with the name MyComponent. Inside, the function returns a React element in JSX syntax:
return <h1>Hello, I'm a functional React Component!</h1>;
Combined, this makes a basic React functional component.
On the last line of the above code block, MyComponent is exported so it can be used later.
Name a Functional Component
Good! Creating a JavaScript function is the way to declare a new functional component.
When you declare a new functional component, you need to give that component a name. On our finished component, our component’s name was MyComponent:
function MyComponent() {
return <h1>Hello world</h1>;
}
Function component names must start with capitalization and are conventionally created with PascalCase! Due to how JSX tags are compiled, capitalization indicates that it is a React component rather than an HTML tag.
This is a React-specific nuance! If you are creating a component, be sure to name it starting with a capital letter so it interprets it as a React component. If it begins with a lowercase letter, React will begin looking for a built-in component such as div and input instead and fail.
Function Component Instructions
//App.js
import React from 'react';
function MyComponent() {
return <h1>Hello, this is a function component body.</h1>;
}
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
Let’s review what you’ve learned so far! Find each of these points in App.js and index.js:
- On line 1 of App.js and index.js, import React from 'react' creates a JavaScript object. This object contains properties that are needed to make React work, such as React.createElement().
- On line 2 of index.js import ReactDOM from 'react-dom/client' creates another JavaScript object. This object contains methods that help React interact with the DOM, such as ReactDOM.createRoot().
- On line 3 of App.js, by writing a JavaScript function, a function component was defined. We can’t see this component quite yet, as it’s more of a factory that produces instances of itself when used. If we want to see it, we need to render it into the DOM.
- Whenever you create a function component, you need to give that function component a name. That name should be written in Pascal case like this: UpperCamelCase.
Something that we haven’t talked about yet is the body of your function component: the pair of curly braces after the function definition and all of the code between those curly braces.
Like all JavaScript functions, this one needs a body. The body will act as a set of instructions, explaining to your function component how it should build a React component.
Here’s what your function body would look like on its own, without the rest of the function declaration syntax. Find it in App.js:
return <h1>Hello, this is a function component body.</h1>;
That doesn’t look like a set of instructions explaining how to build a React component! Yet that’s exactly what it is.
The Return Keyword in Functional Components
When we define a functional component, we essentially define a factory that can build the appropriate combination of elements every time we reference its name. It builds it by consulting a set of instructions that you must provide.
If you’re thinking, “That sounds just like what a regular Javascript function is for”, then you’re right! Functional components can be thought of in a very similar vein to regular Javascript functions, except that their job is to assemble a portion of the interface based on instructions given!
Let’s talk a bit more about these instructions.
For starters, these instructions should take the form of a function declaration body. That means that they will be delimited by curly braces, like this:
function Button() {
// Instructions go here, between the curly braces.
}
Our instructions can include a combination of markup, CSS, and JavaScript to produce the desired result. The one thing we must always include is a return statement.
The function is expected to produce JSX code that can be used to render something onto the browser screen. Thus, when we define functional components, we must return a JSX element.
function BackButton() {
return <button>Back To Home</button>;
}
Of course, this doesn’t quite make <button>Back To Home</button> render onto the browser screen yet. We’ve only defined our component.
Let’s keep going so we can see how to render it and why the return statement was necessary!
Importing and Exporting React Components
There’s a little bit more work we have to do before we can use our defined component and have it rendered onto the DOM.
We previously mentioned that a React application typically has two core files: App.js and index.js. App.js file is the top level of your application, and index.js is the entry point.
So far, we’ve defined the component inside of App.js, but because index.js is the entry point, we have to export it to index.js to render.
Components in React are great because they are reusable. We can keep our component pieces separated, organized, and reusable by putting them into separate files and exporting them to where we need them.
To export them, we can prefix it with the export declaration and specify if it is a default or named export. In this case, we’ll stick with default. If you need a refresher on export, peruse the MDN web docs.
After the function component definition, in App.js, we can default export our component like so:
export default MyComponent;
We can head into our index.js file to import our component from './App':
import MyComponent from './App';
This will allow us to use MyComponent in index.js.
Using and Rendering a Component
Now that we have a defined function component, we can start using it.
We can use it with an HTML-like syntax that resembles a self-closing tag:
<MyComponent />
If you need to nest other components in between, you may also use an opening and corresponding closing tag structure:
<MyComponent>
<OtherComponent />
</MyComponent>
However, to render our component to the browser, we must rely on the .createRoot() and .render() methods from the react-dom library. This should be done in our entry point, index.js.
First, we call the createRoot method to create a React root container for displaying content. React applications typically have a single root DOM node, and everything inside it is managed by React DOM.
In other words, we give createRoot a DOM element to render in, and React will take over managing the DOM inside it.
Here’s an example:
ReactDOM.createRoot(document.getElementById('app'));
Great! Let’s break it down a bit further:
- document.getElementById('app') returns a DOM element from index.html.
- .createRoot() receives the DOM element as the first argument and creates a root for it.
- .createRoot() returns a reference to the root container on which you can call methods like .render().
After the root is created, all that’s left to do is call the .render() method on the returned root and display the React component like so:
ReactDOM.createRoot(document.getElementById('app')).render(<MyComponent />);
From here, React will display <MyComponent /> in the root and make it appear on the screen.
In an application fully built with React, you will only need to do this once. Once this is set up, React will manage the DOM of your application, and any updates to the UI is taken care of efficiently. Adding more components should take place in your top-level App.js file.
//index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import MyComponent from './App';
ReactDOM.createRoot(document.getElementById('app')).render(<MyComponent />);
//App.js
import React from 'react';
function MyComponent() {
return <h1>Hello world</h1>;
}
export default MyComponent;
<!--Index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main id="app">
</main>
<script src="https://content.codecademy.com/courses/React/react-18-course-bundle.min.js"></script>
<script src="/index.compiled.js"></script>
</body>
</html>
Before you go, here’s a recap:
- React applications are made up of components.
- Components are responsible for rendering pieces of the user interface.
- To create components and render them, react and reactDOM must be imported.
- React components can be defined with Javascript functions to make function components.
- Function component names must start with a capitalized letter, and Pascal case is the adopted naming convention.
- Function components must return some React elements in JSX syntax.
- React components can be exported and imported from file to file.
- A React component can be used by calling the component name in an HTML-like self-closing tag syntax.
- Rendering a React component requires using .createRoot() to specify a root container and calling the .render() method on it.
- Phew! That was a lot, but components are at the core of React and they’re one of the reasons why React is such a powerful tool!
Use Multiline JSX in a Component
In this lesson, you will learn some common ways that JSX and React components work together. You’ll get more comfortable with both JSX and React components while picking up some new tricks.
Take a look at this HTML:
<blockquote>
<p>
The world is full of objects, more or less interesting; I do not wish to add any more.
</p>
<cite>
<a target="_blank"
href="https://en.wikipedia.org/wiki/Douglas_Huebler">
Douglas Huebler
</a>
</cite>
</blockquote>
How might you make a React component return this HTML?
import React from 'react';
function QuoteMaker() {
return (
<blockquote>
<p>
The world is full of objects, more or less interesting; I do not wish to add any more.
</p>
<cite>
<a target="_blank"
href="https://en.wikipedia.org/wiki/Douglas_Huebler">
Douglas Huebler
</a>
</cite>
</blockquote>
);
};
export default QuoteMaker;
The key thing to notice in QuoteMaker is the parentheses in the return statement, on lines 4 and 16. Until now, your function component return statements have looked like this, without any parentheses:
return <h1>Hello world</h1>;
However, a multi-line JSX expression should always be wrapped in parentheses! That is why QuoteMaker‘s return statement has parentheses around it.
Use a Variable Attribute in a Component
Take a look at this JavaScript object named redPanda:
import React from 'react';
const redPanda = {
src: 'https://upload.wikimedia.org/wikipedia/commons/b/b2/Endangered_Red_Panda.jpg',
alt: 'Red Panda',
width: '200px'
};
function RedPanda(){
return (
<div>
<h1>Cute Red Panda</h1>
<img
src={redPanda.src}
alt={redPanda.alt}
width={redPanda.width} />
</div>
);
}
export default RedPanda;
Note all the curly brace JavaScript injections inside the return statement. You can, and often will, inject JavaScript into JSX inside the return statement.
Putting Logic in a Function Component
A function component must have a return statement. However, that isn’t all that it can have.
You can also put simple calculations that need to happen before returning your JSX element within the function component.
Here’s an example of some calculations that can be done inside a function component:
function RandomNumber() {
//First, some logic that must happen before returning
const n = Math.floor(Math.random() * 10 + 1);
//Next, a return statement using that logic:
return <h1>{n}</h1>
}
Watch out for this common mistake:
function RandomNumber() {
return (
const n = Math.floor(Math.random() * 10 + 1);
<h1>{n}</h1>
)
}
In the above example, the line with the const n declaration will cause a syntax error, as it should come before the return.
More example:
More example:
//Friend.js
import React from 'react';
const friends = [
{
title: "Yummmmmmm",
src: "https://content.codecademy.com/courses/React/react_photo-monkeyweirdo.jpg"
},
{
title: "Hey Guys! Wait Up!",
src: "https://content.codecademy.com/courses/React/react_photo-earnestfrog.jpg"
},
{
title: "Yikes",
src: "https://content.codecademy.com/courses/React/react_photo-alpaca.jpg"
}
];
function Friend() {
const friend = friends[0];
return (
<div>
<h1>{friend.title}</h1>
<img src={friend.src} />
</div>
);
};
export default Friend;
//App.js
import React from 'react';
import ReactDOM from 'react-dom';
import Friend from './Friend'
function App() {
return <Friend />;
}
export default App
Use a Conditional in a Function Component
How might you use a conditional statement inside of a function component?
Select TodaysPlan.js to see one way of doing it.
Notice that the if statement is located inside of the function component, but before the return statement.
import React from 'react';
function TodaysPlan() {
let task;
let apocalypse = false;
if (!apocalypse) {
task = 'learn React.js'
} else {
task = 'run around'
}
return <h1>Today I am going to {task}!</h1>;
}
export default TodaysPlan;
Event Listener and Event Handlers in a Component
Your function components can include event handlers. With event handlers, we can run some code in response to interactions with the interface, such as clicking.
function MyComponent(){
function handleHover() {
alert('Stop it. Stop hovering.');
}
return <div onHover={handleHover}></div>;
}
In the above example, the event handler is handleHover(). It is passed as a prop to the JSX element <div>. We’ll discuss more on props in a later lesson, but for now, understand that props are information passed to a JSX tag.
The logic for what should happen when the <div> is hovered on is contained inside the handleHover() function. The function is then passed to the <div> element.
Event handler functions are defined inside the function component and, by convention, start with the word “handle” followed by the type of event it is handling.
There’s a small quirk you should watch out for. Take a look at this line again:
return <div onHover={handleHover}></div>
The handleHover() function is passed without the parentheses we would typically see when calling a function. This is because passing it as handleHover indicates it should only be called once the event has happened. Passing it as handleHover() would trigger the function immediately, so be careful!
Here’s a short recap of the concepts introduced in this lesson:
- Function components can return multiple JSX lines by nesting the elements in a parent element.
- Variable attributes can be used inside of a React component with JavaScript injections.
- React components support logic by putting the logic statements above the return statements.
- Components can conditionally return JSX elements by putting conditional statements inside of the components.
- Components can respond to events by defining event handlers and passing them to the JSX elements.
Comments
Post a Comment
Thank you :)