React
Introduction
React is a Javascript library for building user interfaces created and maintained by Facebook. React was first released publicly in July 2013. You can check out the Official React Documents or stick with us for a simpler version.
Why React?
One of the main reasons why people are using React is its ability to reflect changes in the browser DOM when some states changed in just a split second. Developers just need to keep track of changes in states and React will do all the jobs under the hood. Instead of manipulating the browser's DOM directly, React creates a VIRTUAL DOM in memory, where it does all the necessary manipulating, before making the changes in the browser DOM.
Another cool thing about React is that React only changes what needs to be changed. When something changes, React will then compare new states with the previous states and only make changes if they are different.
React is also component-based. This means when developing with React you need to split your UI into smaller components. The advantage of this approach is that the components will encapsulate all the logic inside, you will then have the ability to reuse these components with all of their logic in different places without duplicating your code.
Basic Concepts & Syntax
Hello World
The smallest React example looks like this:
import ReactDOM from "react-dom/client";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<h1>Hello, world!</h1>);
The example above will display a heading saying "Hello, world!" on the page.
JSX
First, let's take a look at this simple example below:
const element = <h1>Hello, world</h1>
The funny tag syntax is neither a string nor HTML.
It is called JSX, and it is a syntax extension to JavaScript. We will use it in React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript.
Let's checkout another example to see what JSX can do
function formatName(user) {
return user.firstName + " " + user.lastName
}
function getGreeting(user) {
const stranger = "Stranger"
if (user) {
return <h1>Hello, {formatName(user)}!</h1>
}
return <h1>Hello, {stranger}.</h1>
}
const user = {
firstName: "Harper",
lastName: "Perez"
}
const element = getGreeting(user)
You can put any valid Javascript expression inside the curly braces {}
in JSX. For example, formatName(user)
or stranger
variable are all valid Javascript expressions. Take note that all the expressions will be executed before React renders JSX into browser DOM.
JSX is also an expression, so you can use JSX inside if
statements or for
loops, assign to variables, accept it as arguments, and return it from functions
Curly braces {}
can also be used to embed a Javascript expression in an HTML tag attribute
const element = <img className={classnames} src={user.avatarUrl}></img>
Warning
Since JSX is closer to JavaScript than to HTML, React DOM uses camelCase property naming convention instead of HTML attribute names.
For example, class
becomes className
in JSX, and tabindex
becomes tabIndex
.
Components
There are 2 ways to define a React Component
- The first one is to create a function that takes in props and returns a JSX (Functional components).
- The second method is to create a
Class
that extends fromReact.Component
, also takes in props from theconstructor
and has a special method calledrender()
to return a JSX (Class components).
You should know!
Because Functional components are too powerful right now and can do most of the things Class components can, so for the beginners, in this documentation, we will only talk about developing React with Functional components.
export default function Welcome(props) {
const { username } = props;
return (
<h1>Hello, {username}</h1>
)
}
To use the created component in other places, you can import it and use it as an HTML tag like this
import Welcome from "components/Welcome"
function Container(props) {
return (
<div>
<Welcome />
</div>
)
}
Note
Always start component names with a capital letter.
React treats components starting with lowercase letters as DOM tags. For example, <div />
represents an HTML div tag, but <Welcome />
represents a component and requires Welcome to be in scope.
Props and States
As mentioned in the previous section, components' input parameters are called props, then what exactly are Props?
Props are unique ways to allow communication between components in React. You can get variables from other components through props, or even a callback function to return data back to them. To pass a variable to a component, you will need to pass the variable through an HTML Tag attribute, like this
function Welcome(props) {
const { username } = props;
return (
<h1>Hello, {username}</h1>
)
}
function Container(props) {
const username = "World"
return (
<div>
<Welcome username={username} />
</div>
)
}
Warning
Props are Read-Only
If Props are variables from parent components, then States are special local/encapsulated variables inside a component that React will keep track of changes to decide whether it should rerender the DOM or not. Since they are special variables, you need to define them using a different way, through a useState hook. We will discuss more about React Hooks in the next section, but for now, just check out the example below for how to define a state
import { useState } from "react"
function Welcome(props) {
const [username, setUserName] = useState()
const handleChangeInput = (event) => {
setUserName(event.target.value)
}
return (
<div>
<h1>Hello, {username}</h1>
<input onChange={handleChangeInput} />
</div>
)
}
username
is the state, and to change its value, you need to call setUserName
function and pass in the new value. React will then check if the new value and the current value are different and then trigger a rerender process if they are.
Warning
Do not modify State directly. You must use the setState
function.
State updates are Asynchronous. After calling setState
, the state value will remain unchanged until React completes its rerender process.
In the example above, you might notice that normal HTML tags also have their own props that after rendered will be remapped to the corresponding DOM element props, like onChange
will be remapped to element.onchange
, which allows you to add event listeners and do more many things.
Advanced Techniques
High Order Component
HOC is an advanced technique in React for reusing component logic. HOCs are not React API. They are a pattern that emerges from React's compositional nature.
Concretely, a higher-order component (HOC) is a function that takes a component and returns a new component.
HOCs are usually used when you want to apply common styles or inject common props, and logic into multiple different components. Check out the example below
(() => {function Input(props) {const handleChange = (e) => { console.log(e.target.value) }return <input onChange={handleChange} />}function Select(props) {const handleChange = (e) => { console.log(e.target.value) }return (<select onChange={handleChange}><option value="option1">Option 1</option><option value="option2">Option 2</option></select>)}const withLabel = (OriginalComponent) => {function WrappedComponent(props) {const { label, ...passThroughProps } = propsreturn (<div><label>{label}</label><br /><OriginalComponent {...passThroughProps} /></div>)}return WrappedComponent}const InputWithLabel = withLabel(Input)const SelectWithLabel = withLabel(Select)function App() {return (<div><InputWithLabel label="Input" /><SelectWithLabel label="Select" /></div>)}return App})()
Context
When coding React, you will sometimes have to pass data down to children at very deep levels, but the middle components don't need to use that data at all. Or your app has some global variables and you want to use them everywhere you want. That's what Context was born for.
To use Context you just need have to define 3 things:
- React.createContext: this function will take in a
defaultValue
and create a Context object to be used later. - Context.Provider: a special component that you can use to wrap any other components, other components will be in the scope of the context and can access the context's values.
- useContext: a React Hook that lets you get the current context's values from any wrapped components.
// Signatures
const MyContext = React.createContext(defaultValue);
<MyContext.Provider value={/* some value */}>
<WrappedComponent />
</MyContext.Provider>
Example
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
That's it. That's all about React that you need to know. Once you can understand deeply and master all of these fundamental concepts, you will be coding React like a pro. In the next section, we will talk more about React Hooks, what are they and what are their functions in the React world.