Introduction
I have created a small timer app in Codesandbox:
I am attempting to cover A LOT in this series of posts. I have included the link to the Codesandbox, so you are encouraged to fork it and play around with it. But if you don't understand everything quite yet, fear not! I promise to cover every single line of code you see.
These series of articles make a few assumptions: you have some experience with React and understand some of its core features (e.g. virtual DOM, class vs. functional component syntax, state management).
Alright, let's dive in!
Part One - useState
In Part One of my React hooks series, we are going to focus on the useState hook.
Import useState from React
import React, { useState } from "react";
React's useState accepts one argument, the initial state and returns a pair of values, the current state and a function to change the state.
const [input, setInput] = useState(0)
const [counter, setCounter] = useState(null)
const [start, setStart] = useState(false)
The intial state of input
is 0
The intial state of counter
is null
The initial state of start
is false
As you can see, the argument passed to useState doesn't have to be an object, it can be a number, or a string, a boolean, etc!
Let's pause for a moment and take a look at a Class component example, which might be helpful to those familiar with the Class syntax.
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
input: 0,
counter: null,
start: false
};
}
The Class example does the exact same thing of setting initial state. But, and this my opinion, the useState hook version is much cleaner and easier to read!
Now what?
The current state of input
, counter
, and start
is accessible throughout our functional component and can be used to evaluate expressions and display information in our render() method.
But the REAL POWER is being able to update the state however we please!
Let's focus on creating a form responsible for setting our Timer and the intial values of input
and counter
:
<form onSubmit={(e) => handleSubmit(e)}>
<h1>Timer</h1>
<input
onChange={handleChange}
min="0"
type="number"
id="seconds"
placeholder="seconds"
style={{textAlign: "center", width: "5rem"}}
/>
<input type="submit" value="Set Timer"/>
</form>
Will render on our screen:
A couple notes
-
min="0"
on a form with atype="number"
won't let the user select a number less than zero. Cool, huh? -
onSubmit={(e) => handleSubmit(e)}
andonChange={handleChange}
are different ways of writing the same thing. I haven't noticed behavioral differences, so if you are reading this and know the difference, please let me know in the comments!
Let's take a look at those functions, handleChange
and handleSubmit
:
const handleChange = (e) => {
setInput(e.target.value)
}
const handleSubmit = (e) => {
e.preventDefault() // stops the submit from performing a re-render
setCounter(input)
e.target.reset() // removes the input from the "seconds" form input
}
Finally! We are using our new fancy hook, useState! inside handleChange
we call setInput(e.target.value)
. This updates the current state to whatever is passed in (isn't it satisfying to watch the number on your screen change as your input changes?). Similarly, we call setCounter(input)
inside handleSubmit
.
Notice what's happening here: handleChange
updates input
, and then handleSubmit
uses the value of input
to set the state of counter
with setCounter
.
(Some readers might wonder why I have two different states for essentially the same value. Without getting into too many spoilers, it made sense for me to have two different versions of state to conditionally render elements on the screen. The value of input
isn't affected by the timer, where as counter
will change every second.)
Okay fine, let's talk about one of those conditional renders before we get to the final implementation of useState, setStart
.
{
start === false && counter !== null && counter !== 0
?
<button style={{fontSize: "1.5rem"}} onClick={handleStart}>START</button>
:
null
}
{
start === true && counter !== 0
?
<button style={{fontSize: "1.5rem"}} onClick={handlePause}>PAUSE</button>
:
null
}
There's a lot to unpack here. First, I'm using something called a ternary operator to evaluate a statement, using boolean values.
Ternary operator syntax
condition ? option1 : option2
If condition === true
run the statement on the left option1
and if condition === false
run the statement on the right option2
In my examples:
First, I set a condition start === false && counter !== null && counter !== 0
If ALL of these conditions are true, run the code on the left:
<button style={{fontSize: "1.5rem"}} onClick={handleStart}>START</button>
If even ONE of these conditions is not true, run the code on the right:
null
It's a very similar situation for the PAUSE button. Basically what's happening is, I only show the START or PAUSE buttons based on certain conditions.
Once the START button is rendered, the user can update or final state start
by activating onClick={handleStart}
const handleStart = () => {
setStart(true)
}
If you recall, the initial state start
is false
. Here we set start
to true
and it will stay true
until something else changes it.
In the next article in this series we will get to see more calls to setInput
, setCounter
and setStart
as we explore the useRef and useEffect hooks.
Final thoughts
Thank you for reading my first entry in the React Hooks Series! As soon as I have the second entry complete, I will post it and update this post with the link.
If you have any questions, suggestions, corrections or general comments, I WOULD LOVE to read them and hear more from all of you!
THANK YOU AND HAPPY CODING
Top comments (4)
Hey, cool!
Some tips on formatting that you may be interested in:
you can save articles into a series, when there are more than 2 articles, all articles within the series will be updated with a navigation like object that links to other articles, like this:
Gaussian Elimination - [Linear Algebra #3]
Liu YongLiang ・ Aug 14 ・ 1 min read
more details here
Thanks! These are some useful tips to know! I’ll see if I can update my post using them later tonight or tomorrow 🙏🙏🙏
kindly share the Role Base Authentication in React, Redux, and Hooks
i am awaiting for this ..
thank to share this react hooks series code