Hooks allow us to use state, life cycle methods and other React features without writing a class component. If we are using hooks, we can have only a functional component in the entire application. For more detail explanation you check React documentation.
The basic hooks are:
Using hooks we can access state without writing a class based component.
To use hooks, first we should import the useState hooks from react. The useState is a function which takes one argument and returns a current state and functions that lets you update it.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = () => {
// Declaring new state variable
const [count, setCount] = useState(0)
return (
<div className='App'>
<h1>{count} </h1>
<button onClick={() => setCount(count + 1)}>Add One</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
We use the setCount to update the state. The initial state value is 0.
In the above example, we used an increment method. Let’s also a decrement method.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = () => {
// Declaring new state variable
const [count, setCount] = useState(0)
return (
<div className='App'>
<h1>{count} </h1>
<button onClick={() => setCount(count + 1)}>Add One</button> <button onClick={() => setCount(count - 1)}>Minus One</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
We can also write separate function instead of writing our function inside the curly brackets.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = () => {
// Declaring new state variable
const [count, setCount] = useState(0)
const addOne = () => {
let value = count + 1
setCount(value)
}
const minusOne = () => {
let value = count - 1
setCount(value)
}
return (
<div className='App'>
<h1>{count} </h1>
<button onClick={addOne}>Add One</button> <button onClick={minusOne}>Minus One</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
Let us do more example about state, in the following example we will develop small application which shows either a dog or cat. We can start by setting the initial state with cat then when it is clicked it will show dog and alternatively. We need one method which changes the animal alternatively. See the code below.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = () => {
// declaring state
const url =
'https://www.smithsstationah.com/imagebank/eVetSites/Feline/01.jpg'
const [image, setImage] = useState(url)
const changeAnimal = () => {
let dogURL =
'https://static.onecms.io/wp-content/uploads/sites/12/2015/04/dogs-pembroke-welsh-corgi-400x400.jpg'
let catURL =
'https://www.smithsstationah.com/imagebank/eVetSites/Feline/01.jpg'
let result = image === catURL ? dogURL : catURL
setImage(result)
}
return (
<div className='App'>
<h1>30 Days Of React</h1>
<div className='animal'>
<img src={image} alt='animal' />
</div>
<button onClick={changeAnimal} class='btn btn-add'>
Change
</button>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
Now, let’s put all the codes we have so far and also let’s implement state using the useState hooks when it is necessary.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
import image from './images/user.jpg'
import './index.scss'
// Fuction to show month date year
const showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
// User Card Component
const UserCard = ({ user: { firstName, lastName, image } }) => (
<div className='user-card'>
<img src={image} alt={firstName} />
<h2>
{firstName}
{lastName}
</h2>
</div>
)
// A button component
const Button = ({ text, onClick, style }) => (
<button style={style} onClick={onClick}>
{text}
</button>
)
// CSS styles in JavaScript Object
const buttonStyles = {
backgroundColor: '#61dbfb',
padding: 10,
border: 'none',
borderRadius: 5,
margin: 3,
cursor: 'pointer',
fontSize: 18,
color: 'white',
}
const Header = (props) => {
const {
welcome,
title,
subtitle,
author: { firstName, lastName },
date,
} = props.data
return (
<header style={props.styles}>
<div className='header-wrapper'>
<h1>{welcome}</h1>
<h2>{title}</h2>
<h3>{subtitle}</h3>
<p>
{firstName} {lastName}
</p>
<small>{date}</small>
</div>
</header>
)
}
const Count = ({ count, addOne, minusOne }) => (
<div>
<h1>{count} </h1>
<div>
<Button text='+1' onClick={addOne} style={buttonStyles} />
<Button text='-1' onClick={minusOne} style={buttonStyles} />
</div>
</div>
)
// TechList Component
const TechList = (props) => {
const { techs } = props
const techsFormatted = techs.map((tech) => <li key={tech}>{tech}</li>)
return techsFormatted
}
// Main Component
const Main = (props) => {
const {
techs,
user,
greetPeople,
handleTime,
changeBackground,
count,
addOne,
minusOne,
} = props
return (
<main>
<div className='main-wrapper'>
<p>Prerequisite to get started react.js:</p>
<ul>
<TechList techs={techs} />
</ul>
<UserCard user={user} />
<Button
text='Greet People'
onClick={greetPeople}
style={buttonStyles}
/>
<Button text='Show Time' onClick={handleTime} style={buttonStyles} />
<Button
text='Change Background'
onClick={changeBackground}
style={buttonStyles}
/>
<Count count={count} addOne={addOne} minusOne={minusOne} />
</div>
</main>
)
}
// Footer Component
const Footer = (props) => {
return (
<footer>
<div className='footer-wrapper'>
<p>Copyright {props.date.getFullYear()}</p>
</div>
</footer>
)
}
const App = (props) => {
const [count, setCount] = useState(0)
const [backgroundColor, setBackgroundColor] = useState('')
const showDate = (time) => {
const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
const month = months[time.getMonth()].slice(0, 3)
const year = time.getFullYear()
const date = time.getDate()
return ` ${month} ${date}, ${year}`
}
const addOne = () => {
setCount(count + 1)
}
// method which subtract one to the state
const minusOne = () => {
setCount(count - 1)
}
const handleTime = () => {
alert(showDate(new Date()))
}
const greetPeople = () => {
alert('Welcome to 30 Days Of React Challenge, 2020')
}
const changeBackground = () => {}
const data = {
welcome: 'Welcome to 30 Days Of React',
title: 'Getting Started React',
subtitle: 'JavaScript Library',
author: {
firstName: 'Asabeneh',
lastName: 'Yetayeh',
},
date: 'Oct 7, 2020',
}
const techs = ['HTML', 'CSS', 'JavaScript']
const user = { ...data.author, image: asabenehImage }
return (
<div className='app'>
{backgroundColor}
<Header data={data} />
<Main
user={user}
techs={techs}
handleTime={handleTime}
greetPeople={greetPeople}
changeBackground={changeBackground}
addOne={addOne}
minusOne={minusOne}
count={count}
/>
<Footer date={new Date()} />
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
Let’s see how we will use hooks in a form
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
// initial state and method to update state
const [firstName, setFirstName] = useState('')
const handleChange = (e) => {
const value = e.target.value
setFirstName(value)
}
return (
<div className='App'>
<label htmlFor='firstName'>First Name: </label>
<input
type='text'
id='firstName'
name='firstName'
placeholder='First Name'
value={firstName}
onChange={handleChange}
/>
<h1>{firstName}</h1>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
We usually use form to handle user information. Let us move to form section and make use the form element.
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const App = (props) => {
const initialState = {
firstName: '',
lastName: '',
country: '',
title: '',
}
const [formData, setData] = useState(initialState)
const onChange = (e) => {
const { name, value } = e.target
setData({ ...formData, [name]: value })
}
const onSubmit = (e) => {
/*
e.preventDefault()
stops the default behavior of form element
specifically refreshing of page
*/
e.preventDefault()
/*
the is the place where we connect backend api
to send the data to the database
*/
console.log(formData)
}
// accessing the state value by destrutcturing the state
const { firstName, lastName, title, country } = formData
return (
<div className='App'>
<h3>Add Student</h3>
<form onSubmit={onSubmit}>
<div>
<input
type='text'
name='firstName'
placeholder='First Name'
value={firstName}
onChange={onChange}
/>
</div>
<div>
<input
type='text'
name='lastName'
placeholder='Last Name'
value={lastName}
onChange={onChange}
/>
</div>
<div>
<input
type='text'
name='country'
placeholder='Country'
value={country}
onChange={onChange}
/>
</div>
<div>
<input
type='text'
name='title'
placeholder='Title'
value={title}
onChange={onChange}
/>
</div>
<button class='btn btn-success'>Submit</button>
</form>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
The above form handles only text types but do have different input field types. Let’s do another form which handle all the different input field types.
// index.js
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const options = [
{
value: '',
label: '-- Select Country--',
},
{
value: 'India',
label: 'India',
},
{
value: 'Sweden',
label: 'Sweden',
},
{
value: 'Norway',
label: 'Norway',
},
{
value: 'Denmark',
label: 'Denmark',
},
]
// mapping the options to list(array) of JSX options
const selectOptions = options.map(({ value, label }) => (
<option key={label} value={value}>
{' '}
{label}
</option>
))
const App = (props) => {
const initialState = {
firstName: '',
lastName: '',
email: '',
title: '',
country: '',
tel: '',
dateOfBirth: '',
favoriteColor: '',
weight: '',
gender: '',
file: '',
bio: '',
skills: {
html: false,
css: false,
javascript: false,
},
}
const [formData, setFormData] = useState(initialState)
const onChange = (e) => {
/*
we can get the name and value like: e.target.name, e.target.value
Wwe can also destructure name and value from e.target
const name = e.target.name
const value = e.target.value
*/
const { name, value, type, checked } = e.target
/*
[variablename] we can make a value stored in a certain variable could be a key for an object, in this case a key for the state
*/
if (type === 'checkbox') {
setFormData({
...formData,
skills: { ...formData.skills, [name]: checked },
})
} else if (type === 'file') {
setFormData({ ...formData, [name]: e.target.files[0] })
} else {
setFormData({ ...formData, [name]: value })
}
}
const onSubmit = (e) => {
/*
e.preventDefault()
stops the default behavior of form element
specifically refreshing of page
*/
e.preventDefault()
const {
firstName,
lastName,
title,
email,
tel,
dateOfBirth,
favoriteColor,
weight,
country,
gender,
bio,
file,
skills,
} = formData
const formattedSkills = []
for (const key in skills) {
console.log(key)
if (skills[key]) {
formattedSkills.push(key.toUpperCase())
}
}
const data = {
firstName,
lastName,
title,
email,
tel,
dateOfBirth,
favoriteColor,
weight,
country,
gender,
bio,
file,
skills: formattedSkills,
}
/*
the is the place where we connect backend api
to send the data to the database
*/
console.log(data)
}
// accessing the state value by destrutcturing the state
const {
firstName,
lastName,
title,
country,
email,
tel,
dateOfBirth,
favoriteColor,
weight,
gender,
bio,
} = formData
return (
<div className='App'>
<h3>Add Student</h3>
<form onSubmit={onSubmit}>
<div className='row'>
<div className='form-group'>
<label htmlFor='firstName'>First Name </label>
<input
type='text'
id='firstName'
name='firstName'
value={firstName}
onChange={onChange}
placeholder='First Name'
/>
</div>
<div className='form-group'>
<label htmlFor='lastName'>Last Name </label>
<input
type='text'
id='lastName'
name='lastName'
value={lastName}
onChange={onChange}
placeholder='Last Name'
/>
</div>
<div className='form-group'>
<label htmlFor='title'>Title </label>
<input
type='text'
id='title'
name='title'
placeholder='Title'
value={title}
onChange={onChange}
/>
</div>
<div className='form-group'>
<label htmlFor='email'>Email </label>
<input
type='email'
id='email'
name='email'
value={email}
onChange={onChange}
placeholder='Email'
/>
</div>
</div>
<div className='form-group'>
<label htmlFor='tel'>Telephone </label>
<input
type='tel'
id='tel'
name='tel'
value={tel}
onChange={onChange}
placeholder='Tel'
/>
</div>
<div className='form-group'>
<label htmlFor='dateOfBirth'>Date of birth </label>
<input
type='date'
id='dateOfBirth'
name='dateOfBirth'
value={dateOfBirth}
onChange={onChange}
placeholder='Date of Birth'
/>
</div>
<div className='form-group'>
<label htmlFor='favoriteColor'>Favorite Color</label>
<input
type='color'
id='color'
name='favoriteColor'
value={favoriteColor}
onChange={onChange}
placeholder='Favorite Color'
/>
</div>
<div className='form-group'>
<label htmlFor='weight'>Weight </label>
<input
type='number'
id='weight'
name='weight'
value={weight}
onChange={onChange}
placeholder='Weight in Kg'
/>
</div>
<div>
<label htmlFor='country'>Country</label> <br />
<select
name='country'
onChange={onChange}
id='country'
value={country}
>
{selectOptions}
</select>
</div>
<div>
<p>Gender</p>
<div>
<input
type='radio'
id='female'
name='gender'
value='Female'
onChange={onChange}
checked={gender === 'Female'}
/>
<label htmlFor='female'>Female</label>
</div>
<div>
<input
id='male'
type='radio'
name='gender'
value='Male'
onChange={onChange}
checked={gender === 'Male'}
/>
<label htmlFor='male'>Male</label>
</div>
<div>
<input
id='other'
type='radio'
name='gender'
value='Other'
onChange={onChange}
checked={gender === 'Other'}
/>
<label htmlFor='other'>Other</label>
</div>
</div>
<div>
<p>Select your skills</p>
<div>
<input type='checkbox' id='html' name='html' onChange={onChange} />
<label htmlFor='html'>HTML</label>
</div>
<div>
<input type='checkbox' id='css' name='css' onChange={onChange} />
<label htmlFor='css'>CSS</label>
</div>
<div>
<input
type='checkbox'
id='javascript'
name='javascript'
onChange={onChange}
/>
<label htmlFor='javascript'>JavaScript</label>
</div>
</div>
<div>
<label htmlFor='bio'>Bio</label> <br />
<textarea
id='bio'
name='bio'
value={bio}
onChange={onChange}
cols='120'
rows='10'
placeholder='Write about yourself ...'
/>
</div>
<div>
<input type='file' name='file' onChange={onChange} />
</div>
<div>
<button>Submit</button>
</div>
</form>
</div>
)
}
const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
Leave a comment, if you find it useful, and do share it with you community. Subscribe to the newsletter and stay updated with latest articles.