What is React anyways? đĩī¸ââī¸
Websites consist of data, whether that's text or boxes. React makes it easy to change the data displayed. Instead of reloading the page, React automatically changes data, giving it the feel of a mobile app.
We're going to recreate this article from scratch to learn React! Skip to the end for the full code.
Thinking in React đ¤
Websites used to be "pages" of data. React splits the page UI up into chunks known as components. We create components by calling a function.
For example, this page has a header, article, sidebar, and a title inside of the article. Each could of these be their own component.
Functions, classes, components - oh my! đ¤¯
Functions, classes, and components are synonymous in React. Every component in React should be a class or function. Classes in JavaScript are special functions. Older React code uses classes, but functions are the standard now.
Every component returns HTML, known as JSX. Traditionally, JavaScript and HTML are separated. In React, functions encapsulate all the code (JS, HTML, even CSS!) for a component.
function Article() {
return <h1>Hello World</h1>;
}
The power of components đĻž
Why use components? Components are reusable, and they can easily manipulate HTML and CSS. Parent components can call children components. For example, our Article component can call Title, Author, and Body children components.
- Article (Parent)
- Title (Child)
- Author (Child)
- Body (Child)
Let's say we build Dev.to and use the same Article component for every article on the site. The data inside the Title, Author, and Body components would need to change. Instead of hardcoding data into our JSX, we can use what is known as props.
function Title() {
return <h1>Fun Fact</h1>
}
function Author() {
return <span>Daniel Curtis</span>
}
function Body() {
return (
<p>The unicorn is the national animal of Scotland.</p>
);
}
function Article() {
return (
<div>
<Title />
<Author />
<Body />
</div>
);
}
Introducing component props đ¨
Props are the way React sends data or functions from one component to another. They are an object of parameters that we can pass into a component when we call it. Props allow us to dynamically change the data of every component, making the component highly reusable. Props can be any data type, even other functions.
function Title(props) {
return <h1>{props.title}</h1>
}
function Author(props) {
return (
<div>
<img src={props.img} alt="Author" />
<span>{props.author}</span>
</div>
);
}
function Body(props) {
return <p>{props.body}</p>;
}
function Article() {
const data = {
title: "Fun Fact",
author: "Daniel Curtis",
body: "The unicorn is the national animal of Scotland."
};
return (
<div>
<Title title={data.title} />
<Author author={data.author} img={data.img_src} />
<Body body={data.body} />
</div>
);
}
In the real world, the data variable would be a bunch of articles. We could map over every article in the data and return an Article component for each one. This would look something like this:
function App() {
const bigData = {/*lots of articles*/}
return (bigData.map((el) => <Article data={el} />));
}
Data manipulation with Hooks âŠī¸
React shines when data is dependant on user interactions. React uses state as a webpage timeline that tracks the state of the webpage.
Hooks are fancy React functions that manipulate state. Every component can create a local state using the useState()
hook. The useState()
hook contains the current state and a function to update it.
Let's say we want to create a Like button. Every time it's clicked, we'll need to call a function to update a variable tracking likes. We can use State for this:
function Likes() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Like
</button>
);
}
Notice that the onClick
event is camelcase instead of all lowercase.
Conditionally rendering components â
We can conditionally render components or information inside of components. For example, we're going to render "Loading..." while our article loads and our article once it is loaded.
Conditionally rendering components and data depending on a webpage's state is what makes React magical.
function Article() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
// notice we moved data to state instead of a variable
if (loading) {
return <h1>Loading...</h1>;
} else {
return (
<div>
<Title title={data.title} />
<Author author={data.author} img={data.img_src} />
<Body body={data.body} />
</div>
);
}
}
The useEffect() Hook âĒī¸
There are a handful of Hooks. And it's possible to create your own custom hook too. useState()
and useEffect()
are by far the most used. useEffect()
is powerful for fetching data from an outside source like an API. useEffect()
is a callback function that can asynchronously update state. It initially runs when the component is called.
useEffect(() => {/* do stuff */}, []);
When we load the Article component, we need to get the article data from an API. The timeline of our Article component would be:
- Article initializes data and loading as states
- Article asks for data by making a fetch request in
useEffect()
- Article continues because
useEffect()
is a callback function - Article returns the conditional HTML for when loading is true
- Article hears back from the fetch request and calls the callback
- Inside the callback, data is set to the info requested and loading is set to false
- Article returns the conditional HTML, this time for when loading is false
In code this would look like:
function Article() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState();
const API_URL = 'https://dev.to/api/articles/354834';
useEffect(() => {
fetch(API_URL)
.then((res) => res.json())
.then(
(result) => {
// On callback, update state
setData(result);
setLoading(false);
},
(error) => {
// Update state; log error
setLoading(false);
console.log(error);
}
);
}, []);
if (loading) {
return <h1>Loading...</h1>;
} else {
return (
<div>
<Title title={data.title} />
<Author
author={data.user.name}
img={data.user.profile_image} />
<Body body={data.body_html} />
</div>
);
}
}
You might be wondering why there's a set of []
in useEffect()
. That's where we add dependencies. Every time something inside of those square brackets changes, useEffect()
runs. We leave them empty so useEffect()
only runs once when the component loads.
Stylish components đĨŗ
React is a UI library, so CSS is a big deal. There's a bunch of different ways you can style components. You can use inline objects, objects, or an external stylesheet with classes. Or you can use a library called styled-components, which extends on the idea of using JavaScript objects for styling.
function StylinDiv() {
const h3Style = {
color: 'purple',
fontSize: '23px' // notice camelcase
}
return (
<div>
{/* Using an external stylesheet */
<h1 className="StylinDiv-h1">Hey there!</h1>
{/* Using an inline object */}
<h2 style={{ color: 'red' }}>Whats up?</h2>
{/* Using an object */}
<h3 style={h3Style}>Goodbye</h3>
</div>
);
}
Whichever method you choose, avoid global styles - make them specific to components.
I'm using an external stylesheet with classes in this example.
Here's the finished product. Fork the pen and try adding tags!
Resources đ
There's a lot more to learn when it comes to React that's beyond the scope of this article. These are some of my favorite learning resources:
Thinking In React is an excellent article on shifting from traditional webpages to components.
I use Hooks in this article. Older React code uses classes and constructors to manipulate state. I highly recommend going through React's Tutorial to understand classes and the "old way."
Traversy Media is an excellent resource for anything frontend related. His crash course is excellent for picking up React quickly.
Create-React-App makes getting started with a React application on your computer quickly. No configuring webpack!
Top comments (3)
And this article also teaches you recursion..
Hey, really great article! I'm currently in the process of remaking the page in React, I'm commenting this specifically here to test out the nesting functionality to reproduce đ¤Ŗ
I was hoping somebody would catch that đ