React Hooks - Part 1


Content
- Case of study
- Why
- What

> Init



> Case of study

+ Step = branch
Class Components
- ES5
- Adopted by convention (idiomatic way of writing js).
> Why ? > Before

import React, { Component } from "react";
export default (CatParts) =>
class CatBoddy extends Component {
constructor(props) {
super(props);
this.state = { requestId: 0}
this.onClick = this.onClick.bind(this);
}
onClick(ev) {
const requestId = Math.random().toString(25).substring(10)
this.setState({requestId});
}
render() {
return (
<div className="list">
<button className="btn" onClick={this.onClick}>
Paw here to get random cats
</button>
{<CatParts requestId={this.state.requestId} />}
</div>
);
}
};"Trade-offs":
- Binding
- Super
- Duplicate code
> Why ? > Before > Duplicated code

import React, { Component } from 'react';
import Cat from './Cat';
import catRequest from '../network/catRequest';
class CatList extends Component {
// TODO: use proptypes checker.
constructor(props) {
super(props);
this.state = {
catList: [],
}
}
async componentDidMount () {
const data = await catRequest(9);
this.setState({catList: data});
}
async componentDidUpdate (prevProps, prevState) {
if (prevProps.requestId !== this.props.requestId) {
const data = await catRequest(9);
this.setState({catList: data});
}
}
render() {
return (
<section className='wrapper'>
{this.state.catList.map(cat => <Cat key={cat.id} url={cat.url} />)}
</section>
)
}
}
export default CatList;
> Why ? > Before > Duplicated code solution (HOC) + autobinding + super (Class Fields)

export default (CatParts) =>
class CatBoddy extends Component {
state = {
catList: [],
requestId: 0,
};
async componentDidMount() {
const data = await catRequest(9);
this.setState({ catList: data });
}
// This is done for educational purposes, yes, I know it is not the best use case
async componentDidUpdate(prevProps, prevState) {
if (prevState.requestId !== this.state.requestId) {
const data = await catRequest(9);
this.setState({ catList: data });
}
}
// Class Fields
onClick = (ev) => {
const requestId = Math.random().toString(25).substring(10);
this.setState({ requestId });
}
render() {
return (
<div className="list">
<button className="btn" onClick={this.onClick}>
Paw here to get random cats
</button>
{
<CatParts
requestId={this.state.requestId}
catList={this.state.catList}
/>
}
</div>
);
}
};import React, { Component } from 'react';
import Cat from './Cat';
import CatBoddy from './CatBoddy';
function CatList({catList}) {
return (
<section className='wrapper'>
{catList.map(cat => <Cat key={cat.id} url={cat.url} />)}
</section>
);
}
export default CatBoddy(CatList);
/*
How about if we have more components who receive the same properties?
*/
function CatList({catList}) {
...
}
export default CatBoddy(CatList1);
....
export default CatBoddy(CatListFooter);
export default CatHOC1(CatHOC2(CatHOC3.....))> Why ? > Before > But ... wrapper hell

Wrapper hell

> Why ? > Before > Reder props ?

Render Props

Class Components
> Why ? > overview

import React, { Component } from "react";
export default (CatParts) =>
class CatBoddy extends Component {
constructor(props) {
super(props);
this.state = { requestId: 0}
this.onClick = this.onClick.bind(this);
}
onClick(ev) {
const requestId = Math.random().toString(25).substring(10)
this.setState({requestId});
}
render() {
return (
<div className="list">
<button className="btn" onClick={this.onClick}>
Paw here to get random cats
</button>
{<CatParts requestId={this.state.requestId} />}
</div>
);
}
};- Binding
- Super
- Duplicate code
- Wrapper hell
- Multiple life-cycles

Classic Approach
> Why ? > Before vs Hooks

Need state ? = Class
Not State ? = Functional Stateless Components
Hooks Approach
Not State / State = Function components! *
Functions are simple!
Hooks
Hooks are functions that let you “hook into” React state and lifecycle features from function components.
> What ? > Hooks


Basic Hooks
- Use State
- Use Efect
- Use Context
import React, { useState, useEffect } from 'react';
import Cat from './Cat';
import catRequest from "../network/catRequest";
function CatList() {
const [catData, setCatData] = useState([]);
const [requestId, setRequestId] = useState(0);
useEffect(() => {
fetchCats();
}, [requestId]);
async function fetchCats () {
const data = await catRequest(10);
setCatData(data);
}
// fetch more cats
const onClick = (ev) => {
const requestId = Math.random().toString(25).substring(10);
setRequestId(requestId);
}
return (
<div className="list">
<button className="btn" onClick={onClick}>
Paw here to get random cats
</button>
<section className='wrapper'>
{catData.map(cat => <Cat key={cat.id} url={cat.url} />)}
</section>
</div>
);
}
export default CatList;> What ? > Hooks > Basics

Use state
- As this. setState but does not merge the old vs new state.
- Returns current state and function.
- Call useState how many times do you need it.
const [catData, setCatData] = useState([]);
const [requestId, setRequestId] = useState(0);
...
async function fetchCats () {
const data = await catRequest(10);
setCatData(data);
}
// fetch more cats
const onClick = (ev) => {
const requestId = Math.random().toString(25).substring(10);
setRequestId(requestId);
}
> What ? > Hooks > Basics
Use efect
- Adds the ability to perform side effects from a function component.
- Same propose to: componentDidMount, componentDidUpdate, and componentWillUnmount
const [catData, setCatData] = useState([]);
const [requestId, setRequestId] = useState(0);
useEffect(() => {
fetchCats();
}, [requestId]);
async function fetchCats () {
const data = await catRequest(10);
setCatData(data);
}
> What ? > Hooks > Basics
Use Context
subscribe to React context without introducing nesting
import React, { useContext } from "react";
import { GlobalContext } from "../context/GlobalState";
export const Balance = () => {
const { transactions } = useContext(GlobalContext);
const amounts = transactions.map(transaction => transaction.amount);
const total = amounts.reduce((acc, item) => (acc += item), 0).toFixed(2);
return (
<>
<h4>Your Balance</h4>
<h1>${total}</h1>
</>
);
};

> What ? > Hooks > Basics
Custom Hooks
> Reuse everywhere!
Extract component logic into reusable functions.
export default function useGetCatsData (requestId, catNumber) {
const [catData, setCatData] = useState([]);
useEffect(() => {
fetchCats();
}, [requestId]);
async function fetchCats () {
const data = await catRequest(catNumber);
setCatData(data);
}
return catData;
}function CatList() {
const [requestId, setRequestId] = useState(0);
const catData = useGetCatsData(requestId, 10);
// fetch more cats
const onClick = (ev) => {
const requestId = Math.random().toString(25).substring(10);
setRequestId(requestId);
}
return (
<div className="list">
<button className="btn" onClick={onClick}>
Paw here to get random cats
</button>
<section className='wrapper'>
{catData.map(cat => <Cat key={cat.id} url={cat.url} />)}
</section>
</div>
);
}
Rules of Hooks
- Call Hooks from React function components.
- Don’t call Hooks inside loops, conditions, or nested functions.
import React, { useState, useEffect } from 'react';
import Cat from './Cat';
import catRequest from "../network/catRequest";
function CatList() {
const [catData, setCatData] = useState([]);
const [requestId, setRequestId] = useState(0);
useEffect(() => {
fetchCats();
}, [requestId]);
async function fetchCats () {
const data = await catRequest(10);
setCatData(data);
}
// fetch more cats
const onClick = (ev) => {
const requestId = Math.random().toString(25).substring(10);
setRequestId(requestId);
}
return (
<div className="list">
<button className="btn" onClick={onClick}>
Paw here to get random cats
</button>
<section className='wrapper'>
{catData.map(cat => <Cat key={cat.id} url={cat.url} />)}
</section>
</div>
);
}
export default CatList;
> Hooks Rules!
Conclusions
> Reuse everywhere!
- Reuse logic: mitigate life-cycle bugs.
- Avoid use of bind and super (class component).
- No more thinking about state vs props.
- Mitigate wrapper hell.
- Easy to use and understand.
- Functions, functions everywhere (few of lightweight life-cycles).

Gracias!

why react hooks - Tyler Mcginnis : https://www.youtube.com/watch?v=eX_L39UvZes
https://www.slideshare.net/CarlosMafla1/introduccin-a-react-hooks-hooke-me-up
React conf 2018 - https://www.youtube.com/watch?v=dpw9EHDh2bM
https://www.slideshare.net/AikdanaiSidhikosol/react-hooks-101
Reack hooks part 1
By Daniel Diaz Giraldo
Reack hooks part 1
- 148