### 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}]"}
    463 views