Functional components passing props are amazing because they are simple, perform fast, and require little code- but they can lead to the much dreaded "wrapper hell" in the quest for maintaining encapsulated components. On the other hand, class components are often confusing to work with for both humans and machines- they often lack a positive developer experience, which makes it more difficult creating a more positive user experience as well. Hooks provide a way for us to use state and lifecycle methods with minimal code- like giving your components super powers!
In general, using props is enough to create an amazing component, but sometimes you need more. Here are some really useful examples to know when to use hooks:
Through experience, you will learn when to use a hook. If you don't think you need them, DON'T use them! The less the better.
import React, { useState } from 'react';
And if we want to use useEffect as well, we can include like this:
import React, { useState, useEffect } from 'react';
Now let's learn how to use them :)
useState
hook:The most important hook, almost unavoidable! The useState helps you initialize a variable and change its value over time without the need of parent components. This is how you can use it:
// variable name setter name initial value (any value) const [ mySuperVariable, mySuperFunction ] = useState( null );
Basically mySuperVariable will be initialized with null
, and then you will be able to re-set its value by calling mySuperFunction
like this:
// here we are re-setting the value of mySuperVariable = 'hello' when the user clicks on a button: <button onClick={() => mySuperFunction('hello')}></button>
useState
hook</strong>import React, { useState } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; const Counter = () => { //initilize a count variable at 0, the setCount function // will be used to re-set the "count" value. const [count, setCount] = useState(0); return ( <div> <h2>{count} likes</h2> {/* Reset count to its previous value + 1 */} <span onClick={() => setCount(count + 1)}>ππ½</span> {/* Reset count to its previous value - 1 */} <span onClick={() => setCount(count - 1)}>ππ½</span> <h3>Like or dislike to increase/decrease</h3> </div> ); }; ReactDOM.render(<Counter />, document.getElementById("root"));
Timer/Clock: You can use the system time to show the current time on the screen, but since time changes all the time, we store it with a state variable.
import React, { useEffect, useState } from "react"; const Clock = (props) => { const [time, setTime] = useState(new Date().toLocaleTimeString()); useEffect(() => { const interval = setInterval(() => { setTime(new Date().toLocaleTimeString()); }, 1000); return () => clearInterval(interval); }, []); return ( <div> <h1>{time}</h1> </div> ); }; Clock.propTypes = {}; export default Clock;
Showing an input on the screen: The best practice to get the content from any input is by storing it on a state variable- this is called "Controlled Input",
import React, { useEffect, useState } from "react"; const ControlledInputForm = (props) => { // holds the value of the input const [currentValue, setValue] = useState(""); return ( <div> <h2>Your name is: {currentValue ? currentValue : "Not defined"}</h2> {/* This is a controlled input because its value is in sync with the stated variable currentValue */} <input type="text" onChange={(e) => setValue(e.target.value)} value={currentValue} placeholder="Please type your name" /> </div> ); }; ControlledInputForm.propTypes = {}; export default ControlledInputForm;
import React, { useState } from "react"; import ReactDOM from "react-dom"; import "./styles.css"; const Modal = () => { /** * Using the useState hook, you have to pay atention to 3 elements: * - opened: a variable that will change over time (can have any name) * - setOpened: a function that resets the value of opened (can by any name) * - useState: this is the hook, it has to be setState and it receives the initial value for "opened" */ const [opened, setOpened] = useState(true); //if opened === true, I show the modal, else i show the button to open the modal return opened ? ( <div> <h1>Hello BreatheCode</h1> <button type="button" onClick={() => setOpened(false)}> Close </button> </div> ) : ( <button type="button" onClick={() => setOpened(true)}> Open </button> ); }; ReactDOM.render(<Modal />, document.getElementById("root"));
| 5. Thousands of other possible applications. | |
Let's explain this hook with a small Modal window example. Here is the live code:
To implement a "Modal Window" we decided to create a hooked variable called opened
that is true
if the modal window has to be shown to the user.
If the user clicks on "close", we simply use the hook function setOpened
to change the value of opened
to false
.
useEffect
hook:useEffect is another amazing hook that you will use if you want to execute some code after the component renders, for example:
const MyComponent = () => { useEffect(() => // whatever you code here will execute only after the first time the component renders , []);// <------ PLEASE NOTICE THE EMPTY ARRAY return <Some HTML>; }
β Please notice the
[]
as the second parameter of the useEffect.
const MyComponent = () => { useEffect(() => // this will run every time the component re-renders if(some_condition){ //this will run only if some_condition is true } );// <------ PLEASE NOTICE THE EMPTY ARRAY IS GONE! return <Some HTML>; }
β This useEffect does not have an empty array
[]
as second parameter.
const MyComponent = () => { useEffect(() => // this will run only the first time the component renders. return () => { // this will run only right before the component unmounts } ,[]);// <------ PLEASE NOTICE THE EMPTY ARRAY return <Some HTML>; }
useState
and useEffect
HooksFor example, let's say I'm building a todo list, and I have to load the list of tasks from an API. I will have to fetch the information right after the component renders for the first time:
const Todos = (props) => { // initialize the tasks variable to an empty array and hook it to setTasks function const [ tasks, setTasks] = useState([]); // this function useEffect will run only one time, when the component is finally loaded the first time. useEffect(() => // here i fetch my todos from the API fetch('https://assets.breatheco.de/apis/fake/todos/user/alesanchezr') .then(r => r.json()) .then(data => setTasks(data)) //here it re-set the variable tasks with the incoming data , []); return <ul>{tasks.map(t => <li>{t.label}</li>)}</ul>; }
β Review the code in depth and live demo by clicking here
For more information, including how to build your own hooks, check out: Official React Documentation
The most efficient way to learn: Join a cohort with classmates like yourself, live streamings, coding jam sessions, live mentorships with real experts and keep the motivation.
From zero to getting paid as a developer, learn the skills of the present and future. Boost your professional career and get hired by a tech company.
Start a career in data science and analytics. A hands-on approach with interactive exercises, chat support, and access to mentorships.
Keep your motivation with this 30 day challenge. Join hundreds of other developers coding a little every day.
Start with Python and Data Science, Machine Learning, Deep Learning and maintaining a production environment in A.I.
Β©4Geeks Academy LLC 2019