Yes, I am aware there are countless tutorials in the market. So, what's the purpose of this article? I aimed to pen down my observations that might help readers connect the dots between the introduction of different concepts and my interpretation of useful stuff in a typical React tutorial. I won't explain everything. You have Google and the Official Documentation for that. Also, I hope that this can be a refresher for anybody who has yet to code in React for some time and would like to get back into the game.
Every Getting Started With React
Do you know how to use create-react-app to bootstrap a new React application, so that you can start coding with a skeleton project structure?
Do you know that you can download React Developer Tools for browsers to help with debugging?
React Elements
Down to the basics, React as a framework, does two things for you.
1. React.createElement()
We want to use JavaScript to solve one fundamental problem that we have with HTML: producing dynamic elements that can be reused in multiple areas. In Vanilla JavaScript, we have the following methods to create an element programmatically:
var newElement = doucment.createElement("div");
newElement.setAttribute("style","color:red");
newElement.innerHTML = "Hello World";
In React, the syntax is slightly easier to work with:
React.createElement("div",{style:{color:"red"}},"Hello World");
// takes in
// 1. tag
// 2. any attributes
// 3. innerHTML (can be another HTML element)
The rendered HTML is as follows:
<div style='color:red'>Hello World</div>
The above example may seem trivial, but one will soon realize the need to initialize a certain element based on some unknown-until-activated conditions, such as a button click. Creating HTML elements on the fly in JavaScript is quite commonplace.
2. ReactDOM.render()
After creating the element in React, we have a simple way to insert the element into the DOM. In Vanilla JavaScript, we can do the following:
document.querySelector("body").appendChild(newElement);
In React, we get to do it this way:
ReactDOM.render(React.createElement("div",{style:{color:"red"}},"Hello World"), document.querySelector("body");
// takes in
// 1. element
// 2. targeted element in the DOM
Introducing...JSX
With the above example, one issue that might present itself is this: do we want to write HTML in JavaScript if we are constructing a complicated element with multiple layers of child elements? The obvious answer is no. It is lengthy and it is error-prone because we are unable to see the structure of HTML clearly.
ReactDOM.render(
React.createElement(
"ul",
{style:{color:"red"}},
React.createElement("li",{style:{color:"brown"}},"Hello Again"),
React.createElement("li",{style:{color:"black"}},"Bye Again"),
React.createElement("li",{style:{color:"blue"}},"Hello Again"),
React.createElement("li",{style:{color:"yellow"}},"Bye Again")
),
document.querySelector("body")
);
So, just like Php that works as a templating language to empower HTML, you get to use this "JavaScript in HTML" syntax called JSX to stay sane when coding elements.
ReactDOM.render(
<ul>
<li style="color:brown">Hello Again</li>
<li style="color:black">Bye Again</li>
<li style="color:blue">Hello Again</li>
<li style="color:yellow">Bye Again</li>
</ul>,
document.querySelector("body")
);
Lengthy still? Yes (we will look at how to solve that later on). But easier to understand what you are writing? Absolutely. By the way, this is possible with Babel, a compiler to do the magic behind the scene.
What Else Can You Do With JSX?
Well, you can write JavaScript within JSX.
One thing to note is that you use className instead of the class keyword when adding attributes to your element.
ReactDOM.render(<h1 className="cool">Hello You</h1>, document.querySelector("body"));
React Components
Remind ourselves that we are here to solve one problem: producing dynamic elements that can be reused in multiple areas. If we see the problem, we can understand what functional components are here for:
Structurally no different from typical JavaScript functions. The added meaning is on its input and output:
- Takes in props - the dynamic aspect, where you receive data from another source
- Returns HTML element(s) - for multiple elements, use React fragments to wrap them. This can be thought of as a typical function returns one output value, if you want to return multiple outputs you will have to use an array etc.
function MusicPlayer(props){
return (
<>
<h2>A fake music player by {props.name}</h2>
<img src=".music/cover" />
</>
)
}
ReactDOM.render(<MusicPlayer name="yong" />, document.querySelector("body"));
If functional components are just functions that churn out HTML elements, then we can combine then in many ways. Notably, we can:
- call a functional component within another functional component
- use functional components multiple times, maybe with different props
function MusicPlayer(props){
return (
<>
<h2>A fake music player by {props.name}</h2>
<img src=".music/cover" />
</>
)
}
function MusicStore(){
return (
<React.Fragment>
<MusicPlayer name="yong" />
<MusicPlayer name="liang" />
</React.Fragment>
)
}
ReactDOM.render(<MusicStore />, document.querySelector("body"));
Rendering
Ok, remember we had an issue with rendering multiple elements in the first example with a list of phrases. Now we will look at two techniques that are often used in React:
- map()
- conditional rendering
Because we can use Javascript in HTML, thanks to JSX, we can loop over a list of items and generate multiple elements of the same structure with different data.
const list = ["Hello Again","Bye Again","Hello Again","Bye Again"];
ReactDOM.render(
<ul>
{list.map(phrase=>(
<li style="color:brown">{phrase}</li>
)}
</ul>,
document.querySelector("body")
);
A list of objects can be rendered in the same way. One thing to note: just like how we need id to track individual elements, React requires a key for each HTML element for tracking. There are multiple ways to do it:
- if the elements have an id, use their id as key as well
- if the elements are unique, use their content as key by turning them to String using .toString()
- use the iterator index for each element
const list = ["Hello Again","Bye Again","Hello Again","Bye Again"];
ReactDOM.render(
<ul>
{list.map(phrase, index=>(
<li key={index} style="color:brown">{phrase}</li>
)}
</ul>,
document.querySelector("body")
);
The other aspect of a dynamic element is that it can be rendered based on certain conditions. In React, it is as simple as using an "if/else" condition to render components. Of course, the cool way to do it is using ternary statements:
"condition" ? "return this if true": "return this if false"
You can see an example of it in this tutorial:
React Hooks Series: useState
James Cox ・ Aug 18 '20 ・ 4 min read
The cool thing is that you can stack it and make it look confusing :)
React Hooks
I have to admit that back in 2019 when I first learned to work with React, I vaguely remember this new feature called React Hooks and I chose not to touch it. Now I guess it is everywhere.
Manage state with useState hook
In principle, hooks are just functions written by someone else to add more functionality to your React components.
In particular, useState hook returns a handle to a piece of data and a way to change that piece of data.
const [status, changeStatus] = useState("initial value");
Note that array destructuring is used here. It means instead of accessing array elements by index, you assign variable names to items in the array.
const [variableA,variableLast] = [ 1, 2];
// calling variableA will give you 1
// calling variableLast will give you 2
You get two powerful stuff with useState (in the above example),
- status, which is initially set to "initial value", and
- changeStatus, a function that can take in a value to update status
<h2>Status: {status}</h2>
<button onClick={()=>changeStatus("it changes")}> Change status </button>
// example 2
<button onClick={()=>changeStatus(status + "and changes")}> More changes</button>
Manage side effects with useEffect hook
So useState hook is used to interact with data and to update the data. useEffect(), on the other hand, is for any side effects that are not related to returning of HTML elements. For example:
- console log
- alert
- fetch data from API
Note that useEffect() is called every time after the functional component renders or re-renders due to state change.
Suppose you have multiple effects that you want to use within a component, you might want to use dependency array to control the invocation of different useEffect hooks that you have:
pass in an array of state as the second argument to useEffect, then it will only be called if that state changes
function MusicPlayer(){
const [status,updateStatus] = useState("start");
useEffect( ()=>{
console.log(status);
}, [status]
);
return (
<>
<h1>Status: {status}</h1>
<button onClick={()=>updateStatus(status+" and"}> And </button>
</>
);
}
Simplify state management with useReducer hook
Finally, the last hook that we will be going through is useReducer(). First of all, we can actually survive without all these hooks. The reason we use them is because of functional abstraction, code reduction, and code reuse. Essentially what we will discover when we write a bunch of code is that certain patterns come up very frequently. In the case of useReducer, one good place to implement it is to replace useState.
When thinking about checkboxes, we almost always need a way to toggle the value. Whether is "ON" to "OFF" or "Start" to "Stop". A simple way to do it is to pass onChange a function that toggles the value.
function simpleComponent(){
const [status, updateStatus] = useState(false);
function toggle(){
updateStatus( status => !status);
};
return (
<input type="checkbox" onChange={toggle}>Change</input>
);
If we need to manipulate the state by doing something with the original state, we can consider useReducer. It takes in a function that you define to manipulate the existing state.
function simpleComponent(){
const [status, toggle] = useReducer(status=>!status, false);
return (
<input type="checkbox" onChange={toggle}>Change</input>
);
Deployment
create-react-app will give us a production build. Simply run
npm run build
You will get the entire project within a folder called "build" that you can give it to hosting service providers such as Netlify.
If you would like to deploy to Github pages for simple react applications that do not deal with routing, you can do it following this tutorial right here on DEV
How to deploy React App to GitHub Pages
Ibrahim Ragab ・ Jun 23 '19 ・ 2 min read
Project Demo
My super simple Github User Finder using React can help you reinforce learning. You can also check out the code at the following repo. (Under src, index.js, is all you need)
tlylt / github-user
Yet another Github user profile search tool. Enter Github username and return the profile picture of that user.
Deployed At The Link Below
https://tlylt.github.io/github-user/
This project was bootstrapped with Create React App.
Available Scripts
In the project directory, you can run:
npm start
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
npm test
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
npm run build
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.
npm run eject
Note: this is a one-way operation. Once you eject
, you can’t go back!
If you…
Credit
This article is written with reference to Eve Porcello 's Learning React.js - LinkedIn Learning Course.
Kudos to all tutorial creators out there, I truly appreciate your dedication and hard work. I feel you🦄
Top comments (0)