TypeScript - Usando tipos nos Hooks

Introdução

Ao migrar do JavaScript para o TypeScript, apesar de todos os benefícios, podem surgir algumas dúvidas durante o desenvolvimento.

Uma das dúvidas que surgiram enquanto eu desenvolvia com essa linguagem, foi referente à tipagem nos hooks. Felizmente, com pouca pesquisa eu pude encontrar [esse artigo] incrível do Ibrahima Ndaw, e compartilhar com vocês através desse post.

useState

O useState permite que você gerencie o estado em sua aplicação React. É o equivalente ao this.state em um componente de classe.

import * as React from "react";

export const App: React.FC = () => {
 const [counter, setCounter] = React.useState<number>(0)
 
 return (
    <div className="App">
      <h1>Result: { counter }</h1>
      <button onClick={() => setCounter(counter + 1)}>+</button>
      <button onClick={() => setCounter(counter - 1)}>-</button>
    </div>
  );
}

Para definir tipos no useState, basta passar o tipo do estado no <>. Você também pode usar <número | null> caso não tenha um estado inicial.

useRef

O useRef retorna um objeto ref que nos permite acessar elementos do DOM.

import * as React from "react";

export const App: React.FC = () => {
  const myRef = React.useRef<HTMLElement | null>(null)

  return (
    <main className="App" ref={myRef}>
      <h1>My title</h1>
    </main>
  );
}

useContext

O useContext permite acessar e consumir um determinado Contexto em um aplicativo React.

import * as React from "react";

interface IArticle {
  id: number
  title: string
}

const ArticleContext = React.createContext<IArticle[] | []>([]);

const ArticleProvider: React.FC<React.ReactNode> = ({ children }) => {
  const [articles, setArticles] = React.useState<IArticle[] | []>([
    { id: 1, title: "post 1" },
    { id: 2, title: "post 2" }
  ]);

  return (
    <ArticleContext.Provider value={{ articles }}>
      {children}
    </ArticleContext.Provider>
  );
}

const ShowArticles: React.FC = () => {
  const { articles } = React.useContext<IArticle[]>(ArticleContext);

  return (
    <div>
      {articles.map((article: IArticle) => (
        <p key={article.id}>{article.title}</p>
      ))}
    </div>
  );
};

export const App: React.FC = () => {
  return (
    <ArticleProvider>
      <h1>My title</h1>
      <ShowArticles />
    </ArticleProvider>
  );
}

Aqui, começamos criando a interface IArticle, que é o tipo de nosso contexto. Em seguida, usamos essa inteface no createContext() para criar um novo contexto e, em seguida, o inicializamos com um array vazio.

Com isso definido, podemos manipular o estado do contexto e definir o tipo em useContext para esperar o array IArticle como valor.

useMemo

O useMemo permite memorizar a saída de uma determinada função. Ele retorna o valor 'memoizado'.

const memoizedValue = React.useMemo<string>(() => {
  computeExpensiveValue(a, b)
}, [a, b])

No exemplo acima, esperamos uma string como valor retornado.

useCallback

O useCallback permite que você 'memoize' uma função para evitar re-renderizações desnecessárias. Ele retorna uma callback 'memoizada'.

type CallbackType = (...args: string[]) => void

const memoizedCallback = React.useCallback<CallbackType>(() => {
    doSomething(a, b);
  }, [a, b]);

No exemplo acima, o useCallback recebe uma string como parâmetro e retorna um valor do tipo void.

Conclusão

Por hora é só pessoal! Eu espero que com o post de hoje possa ter contribuído com boas práticas no TypeScript.

Fique de olho também nos próximos posts sobre o TypeScript, e se surgirem dúvidas ou sugestões, não deixem de mandar aí nos comentários!

Comentários