GithubHelp home page GithubHelp logo

react-pt's Introduction

React+TypeScript Cheatsheets em Português

react + ts logo

Cheatsheets para desenvolvedores com experiência em React que estão iniciando com TypeScript

Web docs | šł≠śĖáÁŅĽŤĮĎ | Espa√Īol | Contribute! | Ask!


ūüĎč Este reposit√≥rio √© mantido por @giseladifini e @swyx. Estamos muito felizes que voc√™ quer experimentar React com Typescript! Se voc√™ perceber algo de errado ou faltando, por favor abra uma issue! ūüĎć


Todas as dicas de React + TypeScript

  • Cheatsheet B√°sico (/README.md) √© focado em ajudar desenvolvedores React a come√ßar a usar TS com React apps
    • Foco nas melhores pr√°ticas com exemplos para copiar e colar.
    • Explica alguns tipos b√°sicos de uso de TS e configura√ß√£o ao longo do caminho.
    • Responde √†s perguntas mais frequentes.
    • N√£o cobre a l√≥gica de tipo gen√©rico em detalhes. Em vez disso, preferimos ensinar t√©cnicas de solu√ß√£o de problemas simples para iniciantes.
    • O objetivo √© se familiarizar com TS sem precisar aprender muito sobre TS.
  • Cheatsheet Avan√ßado (/AVAN√áADO.md) ajuda a mostrar e explicar o uso avan√ßado de tipos gen√©ricos para pessoas que escrevem utilit√°rios/fun√ß√Ķes/props de renderiza√ß√£o/componentes de ordem superior (HOCs) reutiliz√°veis ‚Äč‚Äče bibliotecas TS+React.
    • Possui dicas e truques diversos para usu√°rios profissionais.
    • Conselhos para contribuir com DefinitelyTyped.
    • O Objetivo √© tirar total vantagem sobre o TypeScript.
  • Cheatsheet de migra√ß√£o (/MIGRANDO.md) ajuda a reunir conselhos para a migra√ß√£o incremental de grandes bases de c√≥digo de JS ou Flow, de pessoas que j√° fizeram isso.
    • N√≥s n√£o tentamos convencer as pessoas a mudar, apenas ajudar as pessoas que j√° decidiram isso.
    • ‚ö†ÔłŹ Esta √© uma nova cheatsheet, toda ajuda √© bem-vinda.
  • Cheatsheet de HOCs (/HOC.md) especificamente ensina as pessoas a escrever HOCs com a ajuda de exemplos.
    • Familiaridade com Gen√©ricos √© necess√°rio.
    • ‚ö†ÔłŹ Esta √© uma nova cheatsheet, toda a assist√™ncia √© bem-vinda.

Tabela de conte√ļdos da Cheatsheet b√°sica

Expandir Tabela de Conte√ļdo

Seção 1: Configuração

Pré-requisitos

  1. Uma boa compreens√£o de React.
  2. Familiaridade com os tipos básicos de TypeScript ( O guia de 2ality é de grande ajuda. Se você é completamente novato em TypeScript, dê uma olhada no tutorial de chibicode ).
  3. Ter lido a seção de TypeScript na documentação oficial do React.
  4. Ter lido a seção do React do novo playground de TypeScript ( Opcional: também acompanhar os mais de 40 exemplos na seção de exemplos do playground ).

Este guia sempre assumir√° que voc√™ est√° usando a √ļltima vers√£o de Typescript. Notas para vers√Ķes mais antigas usar√£o a etiqueta <details>.

Ferramentas iniciais de React + TypeScript

Configura√ß√Ķes na nuvem:

Configura√ß√Ķes de desenvolvimento local:

  • Next.js: npx create-next-app -e with-typescript ir√° criar no seu diret√≥rio atual.
  • Create React App: npx create-react-app name-of-app --template typescript ir√° criar em um novo diret√≥rio.
  • Meteor: meteor create --typescript name-of-my-new-typescript-app
  • Ignite para React Native: ignite new myapp
  • TSDX: npx tsdx create mylib para Creating React+TS libraries
Outras ferramentas

Ferramentas menos maduras mas que vale a pena conferir:

  • Vite: npm init vite-app my-react-project --template react-ts (nota - ainda n√£o est√° na vers√£o v1.0, mas √© muito r√°pida).
  • Snowpack: npx create-snowpack-app my-app --template app-template-react-typescript
  • Docusaurus v2 com suporte a TypeScript
  • Parcel
  • JP Morgan's modular: CRA + TS + Yarn Workspaces toolkit. yarn create modular-react-app <project-name>

Manual de configuração:

Import React

import * as React from 'react';
import * as ReactDOM from 'react-dom';

Este é o caminho mais seguro no futuro para importar React. Se você definir --allowSyntheticDefaultImports (ou adicionar "allowSyntheticDefaultImports": true) em seu tsconfig.json, você poderá importar como se faz normalmente em jsx:

import React from 'react';
import ReactDOM from 'react-dom';
Explicação

Por que usar allowSyntheticDefaultImports ao invés de esModuleInterop? Daniel Rosenwasser comentou que é melhor para webpack/parcel. Para consultar mais argumentos dessa discussão wmonk/create-react-app-typescript#214

Voc√™ tamb√©m deveria verificar a nova documenta√ß√£o do TypeScript para descri√ß√Ķes oficiais entre cada flag do compilador!

Seção 2: Primeiros Passos

Componente de Função

Podem ser escritos como fun√ß√Ķes normais que recebem props como argumento e retornam um elemento JSX.

type AppProps = { message: string }; /* também se pode usar uma interface */
const App = ({ message }: AppProps) => <div>{message}</div>;
Por que `React.FC` é desencorajado? E sobre `React.FunctionComponent` / `React.VoidFunctionComponent`?

Você pode ver isso em muitas bases de código React + TypeScript:

const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

No entanto, o consenso geral hoje é que o uso de React.FunctionComponent (ou a abreviação React.FC) é [desencorajado] (facebook/create-react-app#8177). Isto é um ponto de vista, é claro, mas se você concorda e deseja remover React.FC da sua base de código, você pode usar [este jscodeshift codemod] (https://github.com/gndelia/codemod-replace-react- fc-typescript).

Algumas diferenças da versão de "função normal":

  • React.FunctionComponent √© expl√≠cito sobre o tipo de retorno, enquanto a vers√£o normal da fun√ß√£o √© impl√≠cita (ou ent√£o precisa de anota√ß√Ķes adicionais).

  • Fornece verifica√ß√£o de tipos e preenchimento autom√°tico para propriedades est√°ticas como displayName, propTypes e defaultProps.

    • Observe que existem alguns problemas conhecidos usando defaultProps com React.FunctionComponent. Consulte [este problema para obter detalhes] (typescript-cheatsheets/react#87). N√≥s mantemos uma se√ß√£o defaultProps separada para que voc√™ tamb√©m possa consultar.
  • Fornece uma defini√ß√£o impl√≠cita de children (veja abaixo) - no entanto, h√° alguns problemas com o tipo children impl√≠cito (por exemplo, DefinitelyTyped#33006), e √© melhor ser expl√≠cito sobre os componentes que consomem children, de qualquer maneira.

const Title: React.FunctionComponent<{ title: string }> = ({
  children,
  title,
}) => <div title={title}>{children}</div>;
Usando `React.VoidFunctionComponent` ou` React.VFC` como alternativa

A partir da vers√£o [@types/react 16.9.48] (DefinitelyTyped/DefinitelyTyped#46643), voc√™ tamb√©m poder√° usar o tipo React.VoidFunctionComponent ou React.VFC se quiser tipar children explicitamente. Esta √© uma solu√ß√£o provis√≥ria at√© que FunctionComponent n√£o aceite nenhum children por padr√£o (planejado para @types/[email protected]^18.0.0).

type Props = { foo: string };

// OK agora mas futuramente causar√° erro
const FunctionComponent: React.FunctionComponent<Props> = ({
  foo,
  children,
}: Props) => {
  return (
    <div>
      {foo} {children}
    </div>
  ); // OK
};

// OK agora mas futuramente se tornar√° obsoleto
const VoidFunctionComponent: React.VoidFunctionComponent<Props> = ({
  foo,
  children,
}) => {
  return (
    <div>
      {foo}
      {children}
    </div>
  );
};
- _No futuro_, ele poder√° marcar automaticamente os `props` como `readonly` (somente leitura), embora isso seja um ponto discut√≠vel se o objeto `props` for desestruturado na lista de par√Ęmetros.

Na maioria dos casos, faz pouca diferença qual sintaxe é usada, mas você pode preferir a natureza mais explícita de React.FunctionComponent.

Problemas menores

Esses padr√Ķes n√£o s√£o suportados:

** Renderização condicional **

const MyConditionalComponent = ({ shouldRender = false }) =>
  shouldRender ? <div /> : false; // tampouco faça isso em JS
const el = <MyConditionalComponent />; // gera um erro

Isso ocorre porque, devido √†s limita√ß√Ķes do compilador, os componentes de fun√ß√£o n√£o podem retornar nada al√©m de uma express√£o JSX ou null, caso contr√°rio, ele reclama com uma mensagem de erro enigm√°tica dizendo que outro tipo n√£o pode ser atribu√≠do ao Elemento.

const MyArrayComponent = () => Array(5).fill(<div />);
const el2 = <MyArrayComponent />; // gera um erro

Array.fill

Infelizmente, apenas anotar o tipo de função não vai ajudar, então se você realmente precisar retornar outros tipos exóticos que o React suporta, será necessário executar uma declaração de tipo:

const MyArrayComponent = () => (Array(5).fill(<div />) as any) as JSX.Element;

[Veja o coment√°rio de @ferdaber aqui] (typescript-cheatsheets/react#57).

Hooks

H√° suporte para Hooks em @types/react a partir da vers√£o v16.8.

useState

Inferência automática de tipos funciona bem com valores simples

const [val, toggle] = React.useState(false);
//  infere-se que `val` é do tipo boolean
// `toggle` aceita apenas booleans

Veja também no artigo em inglês (utilizando Using Inferred Types se precisar usar um tipo complexo para o qual você depende da inferência.

No entanto, muitos hooks são inicializados com valores nulos e você pode se perguntar como deve fazer para definir o tipo. Declare explicitamente o tipo e use um tipo de união (union type):

const [user, setUser] = React.useState<IUser | null>(null);

// mais adiante...
setUser(newUser);

Voc√™ tamb√©m pode usar asser√ß√Ķes de tipo (type assertions) se um estado for inicializado logo ap√≥s o setup e sempre tiver um valor definido ap√≥s o setup:

const [user, setUser] = React.useState<IUser>({} as IUser);

// mais adiante...
setUser(newUser);

"Mentimos" temporariamente para o compilador de Typescript que {} √© do tipo IUser. Voc√™ deve ent√£o configurar o estado de user ‚ÄĒ se n√£o o fizer, o resto do seu c√≥digo pode depender do fato de que user √© do tipo IUser e isso pode levar a erros em tempo de execu√ß√£o (runtime errors).

useReducer

Voc√™ pode utilizar Uni√Ķes de tipos com propriedades definidas (Discriminated Unions) para actions da fun√ß√£o reducer. N√£o esque√ßa de definir o tipo de retorno, caso cont√°rio, o compilador ir√° inferir o tipo.

const initialState = { count: 0 };

type ACTIONTYPE =
  | { type: "increment"; payload: number }
  | { type: "decrement"; payload: string };

function reducer(state: typeof initialState, action: ACTIONTYPE) {
  switch (action.type) {
    case "increment":
      return { count: state.count + action.payload };
    case "decrement":
      return { count: state.count - Number(action.payload) };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = React.useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({ type: "decrement", payload: "5" })}>
        -
      </button>
      <button onClick={() => dispatch({ type: "increment", payload: 5 })}>
        +
      </button>
    </>
  );
}

Veja no TypeScript Playground

Uso do tipo `Reducer` da biblioteca `redux`

Caso você use a biblioteca redux para escrever a reducer function, ela fornece um helper conveniente do formato Reducer<State, Action> que cuida do tipo do retorno para você.

Assim, o exemplo de reducer acima se torna:

import { Reducer } from 'redux';

export function reducer: Reducer<AppState, Action>() {}

useEffect / useLayoutEffect

Ambos useEffect e useLayoutEffect são usados para executar efeitos colaterais e retornam uma função de limpeza opcional, o que significa que se eles não lidam com retorno de valores, nenhum tipo é necessário. Ao usar useEffect, tome cuidado para não retornar nada além de uma função ou undefined, caso contrário, tanto o TypeScript quanto o React apresentarão error. Isso pode ser sutil ao usar arrow functions:

function DelayedEffect(props: { timerMs: number }) {
  const { timerMs } = props;

  useEffect(
    () =>
      setTimeout(() => {
        /* faça coisas aqui */
      }, timerMs),
    [timerMs]
  );
  // um exemplo ruim! setTimeout implicitamente retorna n√ļmero (tipo number)
  // porque o corpo da arrow function n√£o est√° entre chaves
  return null;
}
Solução para o exemplo acima
function DelayedEffect(props: { timerMs: number }) {
  const { timerMs } = props;

  useEffect(() => {
    setTimeout(() => {
      /* faça coisas aqui */
    }, timerMs);
  }, [timerMs]);
  // melhor; utilize a keyword void para ter certeza de que retornar√° undefined
  return null;
}

useRef

Em TypeScript, useRef retorna uma referência que pode ser somente leitura ou mutável, a depender se o tipo fornecido cobre totalmente o valor inicial ou não. Escolha um que se adapte ao seu caso de uso.

Opção 1: ref de um elemento da DOM

Para acessar um elemento da DOM: forneça apenas o tipo de elemento como argumento e use null como valor inicial. Neste caso, a referência retornada terá um .current somente leitura que é gerenciado pelo React. O TypeScript espera que você dê esta referência à prop ref de um elemento:

function Foo() {
  // - Se possível, seja o mais específico possível. Por exemplo, HTMLDivElement
  // é melhor que HTMLElement e muito melhor que Element.
  // - Em termos técnicos, isso retorna RefObject<HTMLDivElement>
  const divRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    // Observe que ref.current pode ser null. Isso é esperado, porque você pode
    // renderizar condicionalmente o elemento da ref, ou você poderia esquecer de atribuí-lo a um elemento
    if (!divRef.current) throw Error("divRef is not assigned");

    // Agora você tem certeza que divRef.current é um HTMLDivElement
    doSomethingWith(divRef.current);
  });

  // Atribua a ref a um elemento para que o React possa gerenciar-lo pra você
  return <div ref={divRef}>etc</div>;
}

Se você tem certeza de que divRef.current nunca será nulo, também é possível usar o operador de asserção não nulo !:

const divRef = useRef<HTMLDivElement>(null!);
// Mais tarde... não precisa checar se o elemento é nulo
doSomethingWith(divRef.current);

Observe que você está desativando a segurança de tipo aqui - você terá um erro de tempo de execução se esquecer de atribuir a referência a um elemento na renderização ou se o elemento com ref for renderizado condicionalmente.

Dica: Escolhendo qual `HTMLElement` usar

Refs demandam especificidade - não é suficiente apenas especificar qualquer HTMLElement antigo. Se você não souber o nome do tipo de elemento necessário, verifique [lib.dom.ts](https://github.com/microsoft/TypeScript/blob/v3.9.5/lib/lib.dom. d.ts#L19224-L19343) ou cometa um erro de tipo intencional e deixe o compilador lhe dizer o tipo correto:

image

Opção 2: Valor ref mutável

Para ter um valor mutável: forneça o tipo desejado e verifique se o valor inicial pertence totalmente a esse tipo:

function Foo() {
  // Tecnicamente, isto retorna MutableRefObject<number | null>
  const intervalRef = useRef<number | null>(null);

  // Você mesmo gerência a ref (por isso se chama MutableRefObject!)
  useEffect(() => {
    intervalRef.current = setInterval(...);
    return () => clearInterval(intervalRef.current);
  }, []);

  // A ref (intervalRef) não é passado para a prop "ref" de nenhum elemento
  return <button onClick={/* clearInterval the ref */}>Cancel timer</button>;
}

Veja tamb√©m (conte√ļdo em ingl√™s)

useImperativeHandle

Não temos muito ainda sobre esse tema, há uma discussão nas issues do repositório original. Por favor, contribua se puder!

type ListProps<ItemType> = {
  items: ItemType[];
  innerRef?: React.Ref<{ scrollToItem(item: ItemType): void }>;
};

function List<ItemType>(props: ListProps<ItemType>) {
  useImperativeHandle(props.innerRef, () => ({
    scrollToItem() {},
  }));
  return null;
}

Custom Hooks

Se você estiver retornando um array em seu Custom Hook (hooks customizados), você vai querer evitar a inferência de tipo, pois o TypeScript irá inferir um tipo de união (quando, na verdade, você quer tipos diferentes em cada posição do array). Em vez disso, use const assertions do TypeScript 3.4:

export function useLoading() {
  const [isLoading, setState] = React.useState(false);
  const load = (aPromise: Promise<any>) => {
    setState(true);
    return aPromise.finally(() => setState(false));
  };
  return [isLoading, load] as const; // infere [boolean, typeof load] ao invés de (boolean | typeof load)[]
}

Veja no TypeScript Playground

Dessa forma, quando você desestrutura (desctructure), você obtém os tipos certos com base na posição de desestruturação.

Alternativa: definir um tipo de retorno de tupla (tuple)

Se você está tendo problemas com const assertions, você também pode declarar ou definir os tipos do retorno da função:

export function useLoading() {
  const [isLoading, setState] = React.useState(false);
  const load = (aPromise: Promise<any>) => {
    setState(true);
    return aPromise.finally(() => setState(false));
  };
  return [isLoading, load] as [
    boolean,
    (aPromise: Promise<any>) => Promise<any>
  ];
}

Uma fun√ß√£o auxiliar que define o tipe de tuplas automaticamente tamb√©m pode ser √ļtil se voc√™ escrever muitos custom hooks:

function tuplify<T extends any[]>(...elements: T) {
  return elements;
}

function useArray() {
  const numberValue = useRef(3).current;
  const functionValue = useRef(() => {}).current;
  return [numberValue, functionValue]; // o tipo fica (number | (() => void))[]
}

function useTuple() {
  const numberValue = useRef(3).current;
  const functionValue = useRef(() => {}).current;
  return tuplify(numberValue, functionValue); // o tipo fica [number, () => void]
}

Saiba que a equipe do React recomenda que custom hooks que retornam mais de dois valores usem objetos em vez de tuplas.

Leituras sobre Hooks + TypeScript (em inglês):

Se você estiver escrevendo uma biblioteca de Hooks, não esqueça que você também deve expor os tipos para os usuários utilizarem.

Exemploes de bibliotecas React Hooks + TypeScript:

Tem algo a acrescentar? - link para o repositório original.

react-pt's People

Contributors

bnrosa avatar vinicius77 avatar GiselaMD avatar sw-yx avatar

Stargazers

Walefe avatar Guilherme Jun Grillo avatar Giovanni Mendes Mansueto avatar Diogo Bruno  avatar Adilson Gabriel avatar Diego Rondão avatar Rafael avatar Léo Carvalho avatar Diego Nunes avatar Bruno Seghese avatar Breno Cota avatar Nicolas Verçosa avatar Gabriela avatar Bernardo Rosa avatar Márcio Sena Santos Filho avatar Luana R. da Silva avatar Jonatas Antunes avatar Flávio Santos avatar Lucas Martins da Silva avatar Beatriz Oliveira avatar Samuel Caetité avatar Angelilton Epifanio avatar William Goulart avatar Reculos Gerbi Neto avatar Olavio Lacerda  avatar João Marcelo Cardoso Carvalho avatar Jilles Moraes Cardoso avatar Arley Lobato avatar Luiz Carlos Wagner avatar Matheus Benites avatar Helder Chaves Leite Junior avatar eklauberg avatar Antoniel Magalhães avatar Ricardo Canelas avatar Luís Clício avatar Neilton Gomes avatar Bruno Martins avatar Ediberto B.O avatar Marcelo H M Dias avatar Ana Carolina avatar Bruno Rodrigues dos Santos avatar Felipe Alves Patricio avatar Gisela Miranda Difini avatar

Watchers

James Cloos avatar Vinicius Cerqueira Bonif√°cio avatar Marcelo H M Dias avatar Felipe Alves Patricio avatar Gisela Miranda Difini avatar

react-pt's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ūüĖĖ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ūüďäūüďąūüéČ

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ‚̧ԳŹ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.