Components in React are independent, reusable pieces of UI. A typical web page may consist of a navbar, content area & footer. In React, we create these areas as components (which in turn may consist of other components!). It saves on code duplication & as weâll see, allows for an immense amount of flexibility.
Another way to think of components is like JavaScript functions. Instead of receiving arguments, they receive âpropsâ, and then return React elements to build what we see on the screen!
Components
In fact, in React â everything is a component! Even standard HTML tags are components, theyâre built-in and added by default.
Letâs take a look at an example:
import React from 'react'
import ReactDOM from 'react-dom'
ReactDOM.render(<h1>I'm a component!</h1>,
document.getElementById('myapp'))
Here weâve used JSX to insert<h1>I'm a component!</h1>
 into an element with id of myapp
. Our h1
 is considered a component, courtesy of React.DOM
, and in fact so are all HTML tags. You can check them out by typing React.DOM
 into your browser console.
Building custom components
This is great, but how do we build our own components? This is where React exceeds, it gives us the ability to build UIâs by composing our own custom components.
We can define components in 2 ways, letâs take a look at each now:
Function components
Function components are really just JavaScript functions:
function Greeting(props) {
return <h1>Hello, {props.username}!</h1>;
}
What makes this function a React component, is that it accepts âpropsâ (or properties) as an argument with data, and then it returns a React element.
Class components
ES6 Classes can also be used to create components:
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.username}!</h1>;
}
}
Both our above code examples are equivalent â and perfectly valid ways to create components.
Until recently in the React world, class components were used more frequently â as class components allowed components to be defined with their own state (Iâll be writing about state in my next article!).
However, with the advent of React Hooks, function components are now much more powerful than before, and we may see this trend switch back.
Hooks are outside the scope of this article! So let's continue on with components & props..
Rendering components
We can render our elements, which represent DOM tags:
const element = <div />;
And we can also render our elements with user-defined components:
const element = <Greet username="Bruce" />;
When an element contains a user-defined component, it will pass the JSX attributes to the component as an object. In React this object is what we call âpropsâ.
Props
So âpropsâ are how our components get their properties.
Letâs see this in action:
function Greeting(props) {
return <h1>Hello, {props.username}!</h1>;
}
const element = <Greet username="Bruce" />;
ReactDOM.render(
element,
document.getElementById('root')
);
This code will render âHello, Bruce!â on the page.
What is happening here?
ReactDOM.render()
 is called with theÂ<Greet username="Bruce" />
 element.- React calls theÂ
Greet
 component withÂ{name: 'Bruce'}
 as the props. - OurÂ
Greet
 component returns aÂ<h1>Hello, Bruce!</h1>
 element as the result. - React DOM updates the DOM to matchÂ
<h1>Hello, Bruce!</h1>
.
Note: Always start component names with a capital letter! Why? React treats components starting with lowercase letters as DOM tags.
Props in function components
It should be noted that when working with components that have multiple children (see below with h1
 and p
), each child component gets its props from the parent.
When using a function component, props are all that gets passed, theyâre available by adding props
 as the function argument:
const BlogPostInfo = props => {
return (
<div>
<h1>{props.title}</h1>
<p>{props.description}</p>
</div>
)
}
Props in class components
In a class component, props are passed by default. Theyâre accessible as this.props
 in a component instance.
import React, { Component } from 'react'
class BlogPostInfo extends Component {
render() {
return (
<div>
<h1>{this.props.title}</h1>
<p>{this.props.description}</p>
</div>
)
}
}
Passing props to child components is a great way to pass values around in your applications. Components either hold data (have state) or receive data through their props.
Extra creditsâŚ
Now that we know how to use props with our components. Letâs take a look at some of the more common tasks weâre likely to encounter:
Prop defaults
If any values are missing when a component is initialized, weâll need to provide a default. Defaults can be specified, like so:
BlogPostInfo.propTypes = {
title: PropTypes.string,
description: PropTypes.string
}
BlogPostInfo.defaultProps = {
title: '',
description: ''
}
Passing props
When we initialize a component, we pass in our props like so:
const desc = 'My blog post description'
<BlogPostInfo title="My blog post title" description={desc} />
If we are working with strings, we can pass in our prop as a string (as we have above with âtitleâ. Otherwise, we use variables, as we have with the above description being set to desc
.
The âchildrenâ prop
The children
 prop is a little different from the norm. It contains the value of anything that is passed in the body
 of the component, for example:
<BlogPostInfo title="My blog post title" description="{desc}">
More words
</BlogPostInfo>
In this example, inside BlogPostInfo
 we could access "More words" via this.props.children
.
Components in Components
Components can include other components in their output.
Itâs perfectly fine to create a MyApp
 component, that renders Greet
 a number of times:
function Greet(props) {
return <h1>Hello, {props.username}!</h1>;
}
function MyApp() {
return (
<div>
<Greet name="Bruce" />
<Greet name="Bethany" />
<Greet name="Bilbo" />
</div>
);
}
ReactDOM.render(
<MyApp />,
document.getElementById('root')
);
Props are read-only!
Whether your component is declared as a function or class component, it can never modify its own props. See the following example:
function sum(a, b) {
return a + b;
}
This is a âpureâ function, as it doesnât attempt to change its inputs, and will always return the same result for the same inputs.
An âimpureâ function is a function that changes its own input:
function withdraw(account, amount) {
account.total -= amount;
}
In React, this is a no-no! Every component must act like a pure function with respect to its prop.
My next article will be looking at âstateâ in React. With state, our components are able to change their output in response to triggers such as user actions or network responses â without being in violation of this rule.
Conclusion
And there we go! Weâve covered the basics of building components, as well as seeing how they fit into the overall structure of our React apps. Weâve also seen how to use props to give properties to our components. And weâve looked at some of the common tasks weâll likely run into when working with components & props.
Related Posts:
A little about me..
Hey, Iâm Tim! đ
Iâm a freelance business owner, web developer & author. I teach both new and experienced freelancers how to build a sustainable and successful freelancing business. Check out my Complete Guide to Freelancing if you'd like to find out more.
While you're here, you can browse through my blogs where I post freelancing tips, code tutorials, design inspiration, useful tools & resources, and much more! You can also join the newsletter, or find me on X.
Thanks for reading! đ