### Quem sou eu?
#### Front-End Developer por aproximadamente 2 anos
---
### Quer acompanhar pelo celular?
<p style="font-weight: 700; font-size: 3rem;">
http://tiny.cc/hooks-geru
</p>
<p>
<img width="40%" src="https://tiny.cc/hooks-geru/qr/image/L/150" alt="qr-code" />
</p>
---
### O que são *hooks* e os *custom hooks*?
---
<h4 style="text-align: left;">Hooks são uma adição ao React (a partir da versão 16.8) onde se permite fazer uso do <i>state</i> e outras <i>features</i> do React sem a criação de <i>classes</i>.</h4>
---
<h4 style="text-align: center;">Implementação <i>exemplo</i> com classe</h4>
```jsx
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
myHeading: 'sem mudanças'
}
this.changeHeading = this.changeHeading.bind(this);
};
changeHeading() {
this.setState({
myHeading: 'texto alterado'
});
};
render() {
const {myHeading} = this.state;
return (
<h1>Meu texto deste H1 é {myHeading}</h1>
<button
type="button"
onClick={this.changeHeading}
>
Click me to change
</button>
);
};
};
```
---
<h4 style="text-align: center;">Implementação <i>exemplo</i> com function components (usando hooks de estado)</h4>
```jsx
import {useState} from 'react';
function MyComponent() {
const [myText, setMyText] = useState('sem mudanças');
return (
<h1>Meu texto deste H1 é {myText}</h1>
<button
type="button"
onClick={() => setMyText('texto alterado')}
>
Click me to change
</button>
);
}
```
---
### Regras imprescindíveis para o uso dos `hooks`
---
<h4>Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions.</h4>
---
<h4 style="text-align: left;">Only call Hooks from React function components. Don’t call Hooks from regular JavaScript functions. (There is just one other valid place to call Hooks — your own custom Hooks. We’ll learn about them in a moment.)</h4>
<h5 style="text-align: left;">Mais informações na documentação do <a href="https://reactjs.org/docs/hooks-intro.html" target="_blank">React Hooks</a>.</h5>
---
### Exemplos de *custom hooks*
---
<h3 style="text-align:left;">
- useIsMobile
</h3>
<h4 style="text-align: left;">Esse custom hook aqui pode ser implementado de algumas formas.</h4>
<h4 style="text-align: left;">Neste exemplo, o hook recebe por parâmetro (análogo ao <i>constructor</i> de classe) duas propriedades, a largura da janela para ser testada e o <i>userAgent</i> do navegador.</h4>
---
```jsx
import {useIsMobile} from '@hooks/useIsMobile';
const isMobile = useIsMobile({
width: 768,
customAgent: global.navigator.userAgent
});
```
---
<h4 style="text-align: left;">O uso deste custom hook também pode ser feito por demanda, ou seja, por componente ou pode ser conectado no topo do seu App realizando um disparo à <i>store</i> para que todo o sistema fique consciente da mobilidade.</h4>
---
<h4 style="text-align: center;">Exemplo conectado à <i>store</i>: (como o estado de <i>isMobile</i> não muda toda hora, é interessante colocá-lo no topo da aplicação para <i>re-render</i> perante mudança do estado).</h4>
```jsx
import {useDispatch} from 'react-redux';
import {useIsMobile} from '@hooks/useIsMobile';
import {setIsMobile} from '@store/actions';
function App() {
const isMobile = useIsMobile({
width: 768,
customAgent: global.navigator.userAgent
});
const dispatch = useDispatch();
dispatch(setIsMobile(isMobile));
...
}
```
---
<h4 style="text-align: center;">Exemplo utilizado por demanda:</h4>
```jsx
import {useIsMobile} from '@hooks/useIsMobile';
function Component() {
const isMobile = useIsMobile({
width: 768,
customAgent: global.navigator.userAgent
});
return (
<div>
<h1>{isMobile ? "This is on mobile" : "This is on desktop"}</h1>
</div>
);
}
```
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
<i>useIsMobile</i> custom hook faz uso de:
</h4>
<div style="align-self: flex-start;">
<ol>
<li>
useState
</li>
<li style="margin-bottom: 1rem;">
useEffect
</li>
<a style="display: block;" href="https://codesandbox.io/s/useismobile-k8p9t" target="_blank">Preview me! (on demand)</a>
<a style="display: block;" href="https://codesandbox.io/s/react-redux-hooks-store-thunk-y6gds" target="_blank">Preview me! (redux connected)</a>
</ol>
</div>
</div>
---
<h3 style="text-align:left;">
- useModalWrapper
</h3>
<h4 style="text-align: left;">Este custom hook faz uso da habilidade de <a href="https://reactjs.org/docs/portals.html" target="_blank"><i>Portals</i></a> do React onde se é possível montar um componente em qualquer outro lugar do DOM independente de contexto. Novamente, em analogia a um construtor, <i>bindToElement</i> representa o nó desejado para a renderização.</h4>
---
```jsx
import {useModalWrapper} from '@hooks/useModalWrapper';
const {
ModalWrapper,
isOpen,
openModal,
closeModal
} = useModalWrapper({
bindToElement: global.document.getElementById('modal-root')
});
return (
<div>
{
isOpen && (
<ModalWrapper backdrop={true} fade={true}>
<MyBeautifulModal closeModal={closeModal} />
</ModalWrapper>
);
}
<button type="button" onClick={() => openModal()}>
Click to Open
</button>
</div>
);
```
---
#### Propriedades retornadas a partir deste *hook*:
1. *ModalWrapper*, que nada mais nada menos é, um HOC.
2. *isOpen*, como o nome mesmo já diz, nos informa se a modal está aberta ou não.
3. *openModal*, atuando diretamente como controle para a abertura da modal.
4. *closeModal*, assim como a *openModal* porém para seu fechamento.
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
<i>useModalWrapper</i> custom hook faz uso de:
</h4>
<div style="align-self: flex-start;">
<ol>
<li>
useState
</li>
<li>
useEffect
</li>
<li>
useRef
</li>
<li style="margin-bottom: 1rem;">
React e ReactDOM
</li>
<a href="https://codesandbox.io/s/usemodal-as-a-wrapper-uit30" target="_blank">Preview me!</a>
</ol>
</div>
</div>
---
<h3 style="text-align:left;">
- useIsLoading
</h3>
<h4 style="text-align: left;">É um hook controverso quanto a sua utilidade.</h4>
<h4 style="text-align: left;">O componente que necessitar do <i>Loading</i> a partir de alguma ação assíncrona não precisará acessar a <i>store</i> de forma alguma.</h4>
<h4 style="text-align: left;">Observação: utilizado apenas com aplicações com gerenciamento de estado global como por exemplo o <i>redux</i> ou <i>context API</i>.</h4>
---
```jsx
import {useIsLoading} from '@hooks/useIsLoading';
const [isLoading, Loading] = useIsLoading();
if (isLoading) return <Loading />;
return <MyComponentAfterLoading />;
```
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
<i>useIsLoading</i> custom hook faz uso de:
</h4>
<div style="align-self: flex-start;">
<ol>
<li>
React
</li>
<li>
useSelector (react-redux)
</li>
<li style="margin-bottom: 1rem;">
Componente de Loading
</li>
<a href="https://codesandbox.io/s/useisloading-connected-9s8gt" target="_blank">Preview me!</a>
</ol>
</div>
</div>
---
<h3 style="text-align:left;">
- useAuth
</h3>
<h4 style="text-align: left;">Este custom hook pode ser implementado de diversas formas e isso pode variar de acordo com a necessidade e implementação de cada projeto, no entanto a sua ideia é basicamente a mesma, prover mecanismos de autenticação para páginas.</h4>
---
```jsx
import {useLogin, useLogout} from '@hooks/useAuth';
const {isLogged, doLogin, authInfo} = useLogin();
const {doLogout} = useLogout();
```
---
#### Propriedades retornadas a partir deste *hook*:
1. *isLogged*, retorna verdadeiro ou falso para a condicional de autenticado ou não no sistema.
2. *doLogin*, dispara a ação para realizar a autenticação.
3. *authInfo*, retorna objeto com informações pertinentes à autenticação.
4. *doLogout*, dispara a ação pertinente para deslogar do sistema.
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
<i>useAuth</i> custom hook faz uso de:
</h4>
<div style="align-self: flex-start;">
<ol>
<li>
useEffect
</li>
<li>
useSelector e useDispatch (react-redux)
</li>
<li style="margin-bottom: 1rem;">
useHistory, useLocation (react-router-dom)
</li>
</ol>
</div>
</div>
---
<h3 style="text-align:left;">
- useInput
</h3>
<h4 style="text-align: left;">Este custom hook é também bem simples no entanto um tanto quanto útil quando se é preciso lidar com <i>inputs</i> de formulário.</h4>
<h4 style="text-align: left;">Bem direto, o custom hook retorna os valores dos inputs e o <i>handler</i> de <i>onChange</i>. A mágica do controle de estado está toda por dentro do <i>useInput</i>.</h4>
---
```jsx
import {useInput} from '@hooks/useInput';
const [values, handleChange] = useInput();
function handleSubmit(e) {
e.preventDefault();
console.log("values", values);
}
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
placeHolder="Name"
onChange={handleChange}
/>
<input
type="text"
name="surname"
placeHolder="Sobrenome"
onChange={handleChange}
/>
...
</form>
```
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
<i>useInput</i> custom hook faz uso de:
</h4>
<div style="align-self: flex-start;">
<ol>
<li style="margin-bottom: 1rem;">
useState
</li>
<a href="https://codesandbox.io/s/useinput-v66nu">Preview me!</a>
</ol>
</div>
</div>
---
<h3 style="text-align: left; margin-bottom: 3rem;">Resumo do conteúdo</h3>
<h4 style="text-align: left;">Falamos sobre uma breve introdução ao uso dos <i>hooks</i> com React e algumas de suas possíveis utilizações.</h4>
<h4 style="text-align: left;">As possibilidades são as mais variadas e provavelmente alguém já as fez, no entanto nada nos impede de criamos as nossas próprias de acordo com a necessidade de cada um.</h4>
---
### Dúvidas e sugestões (e reclamações)?
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h3 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
Links dos conteúdos apresentados
</h3>
<div style="align-self: flex-start;">
<ol>
<li>
<a href="https://reactjs.org/docs/hooks-intro.html" target="_blank">React Hooks Introduction</a>
</li>
<li>
<a href="https://reactjs.org/docs/portals.html" target="_blank">React Portals</a>
</li>
<li style="margin-bottom: 1rem;">
<a href="https://github.com/kaimallea/isMobile" target="_blank">ismobilejs</a>
</li>
<li style="margin-bottom: 1rem;">
<a href="https://usehooks.com" target="_blank">useHooks</a>
</li>
</ol>
</div>
</div>
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h3 style="text-align: left; margin: 0rem 3rem; padding: 1rem;">
Obrigado!
</h3>
<h4 style="text-align: left; margin: 1rem 3rem; padding: 1rem;">
Você pode me encontrar no
</h4>
<div style="align-self: flex-start;">
<ul>
<li>
<a href="https://github.com/olavoparno" target="_blank">GitHub</a>
</li>
<li>
<a href="https://www.linkedin.com/in/olavoparno" target="_blank">LinkedIn</a>
</li>
<li style="margin-bottom: 1rem;">
ou <a href="mailto:olavoparno@gmail.com">mande-me um e-mail</a>
</li>
</ul>
</div>
</div>
---
<div style="display: flex; justify-content: center; align-items: flex-start; flex-direction: column;">
<h3 style="text-align: left; margin: 0rem 3rem; padding: 1rem;">
A Geru está contratando! Veja nos links abaixo!
</h3>
<div style="align-self: flex-start;">
<ul>
<li>
<a href="https://geru.gupy.io" target="_blank">Vagas Geru</a>
</li>
<li>
<a href="https://www.linkedin.com/company/geru" target="_blank">LinkedIn Geru</a>
</li>
<li>
<a href="https://www.instagram.com/geru_br/?hl=en" target="_blank">Instagram</a>
</li>
</ul>
</div>
</div>
---
{"metaMigratedAt":"2023-06-15T03:46:18.123Z","metaMigratedFrom":"YAML","title":"Custom Hooks Slide","breaks":true,"description":"React Custom Hooks preview","slideOptions":"{\"transition\":\"slide\",\"spotlight\":{\"enabled\":false},\"controls\":false}","contributors":"[{\"id\":\"1a516985-4c9a-4950-9f24-3832b4bea8c5\",\"add\":20346,\"del\":8746}]"}