- Notifications
You must be signed in to change notification settings - Fork12
React Typescript Cheatsheet in Portuguese 🇧🇷
License
typescript-cheatsheets/react-pt
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
👋 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 umaissue! 👍
- Cheatsheet Básico (
/README.md) é focado em ajudar desenvolvedores React a começar a usar TS com Reactapps- 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 aprendermuito 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 ebibliotecas TS+React.- Possui dicas e truques diversos para usuários profissionais.
- Conselhos para contribuir com DefinitelyTyped.
- O Objetivo é tirartotal 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 comGenéricos é necessário.
⚠️ Esta é uma nova cheatsheet, toda a assistência é bem-vinda.
Expandir Tabela de Conteúdo
- Seção 2: Primeiros Passos
- Componente de Função
- Hooks
- useState
- useReducer
- useEffect
- useRef
- useImperativeHandle
- Hooks Customizados
- Componentes de Classe
- Talvez você não precise do
defaultProps - "Tipando"
defaultProps - Consumindo Props de um Componente com defaultProps
- Discussões e Conhecimentos Diversos
- Tipos ou Interfaces?
- Exemplos básicos do tipo Prop
- Exemplos úteis do tipo React Prop
- getDerivedStateFromProps
- Formulários e Eventos
- Context
- Exemplo Básico
- Exemplo Extendido
- forwardRef/createRef
- Portais
- Limites de erros
- Concurrent React/React Suspense
- Manual de resolução de problemas: Tipos
- Manual de resolução de problemas: Operadores
- Manual de resolução de problemas: Utilitários
- Manual de resolução de problemas: tsconfig.json
- Manual de resolução de problemas: Erros en tipos oficiais
- Bases de código de React + TypeScript recomendadas para aprender
- Ferramentas e integração em editores
- Linting
- Outros recursos sobre React + TypeScript
- Discussões recomendadas sobre React + TypeScript
- Hora de realmente aprender TypeScript
- Aplicação de Exemplo
- Minha pergunta não foi respondida aqui!
- Uma boa compreensão deReact.
- Familiaridade com os tipos básicos deTypeScript (O guia de 2ality é de grande ajuda. Se você é completamente novato em TypeScript, dê uma olhada notutorial de chibicode ).
- Ter lidoa seção de TypeScript na documentação oficial do React.
- Ter lidoa seção do React do novo playground de TypeScript ( Opcional: também acompanhar os mais de 40 exemplos na seção de exemplos doplayground ).
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>.
Configurações na nuvem:
- Playground do TypeScript com React apenas se você estiver depurando tipos (e relatando problemas), não para executar código.
- CodeSandbox - IDE na nuvem, inicializa super rápido.
- Stackblitz - IDE na nuvem, inicializa super rápido.
Configurações de desenvolvimento local:
- Next.js:
npx create-next-app -e with-typescriptirá criar no seu diretório atual. - Create React App:
npx create-react-app name-of-app --template typescriptirá 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 mylibpara Creating React+TSlibraries
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 comsuporte a TypeScript
- Parcel
- JP Morgan's
modular: CRA + TS + Yarn Workspaces toolkit.yarn create modular-react-app <project-name>
Manual de configuração:
- O guia de Basarat para umaconfiguração manual de React + TypeScript + Webpack + Babel.
- Em particular, certifique-se de ter instalado
@types/reacte@types/react-dom.(Leia mais sobre o projeto DefinitelyTyped caso você não esteja familiarizado ). - Existem também muitosboilerplates de React + Typescript. Por favor consultenossa lista de outros recursos.
import*asReactfrom'react';import*asReactDOMfrom'react-dom';
Este é ocaminho mais seguro no futuro para importar React. Se você definir--allowSyntheticDefaultImports (ou adicionar "allowSyntheticDefaultImports": true) em seutsconfig.json, você poderá importar como se faz normalmente em jsx:
importReactfrom'react';importReactDOMfrom'react-dom';
Explicação
Por que usarallowSyntheticDefaultImports ao invés deesModuleInterop?Daniel Rosenwasser comentou que é melhor para webpack/parcel. Para consultar mais argumentos dessa discussãowmonk/create-react-app-typescript#214
Você também deveria verificara nova documentação do TypeScript para descrições oficiais entre cadaflag do compilador!
Podem ser escritos como funções normais que recebemprops como argumento e retornam um elemento JSX.
typeAppProps={message:string};/* também se pode usar uma interface */constApp=({ 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:
constApp:React.FunctionComponent<{message:string}>=({ message})=>(<div>{message}</div>);
No entanto, o consenso geral hoje é que o uso deReact.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 removerReact.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,propTypesedefaultProps.- Observe que existem alguns problemas conhecidos usando
defaultPropscomReact.FunctionComponent. Consulte [este problema para obter detalhes] (typescript-cheatsheets/react#87). Nós mantemos uma seçãodefaultPropsseparada para que você também possa consultar.
- Observe que existem alguns problemas conhecidos usando
Fornece uma definição implícita de
children(veja abaixo) - no entanto, há alguns problemas com o tipochildrenimplícito (por exemplo, DefinitelyTyped#33006), e é melhor ser explícito sobre os componentes que consomemchildren, de qualquer maneira.
constTitle:React.FunctionComponent<{title:string}>=({ children, title,})=><divtitle={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 tipoReact.VoidFunctionComponent ouReact.VFC se quiser tiparchildren explicitamente. Esta é uma solução provisória até queFunctionComponent não aceite nenhumchildren por padrão (planejado para@types/react@^18.0.0).
typeProps={foo:string};// OK agora mas futuramente causará erroconstFunctionComponent:React.FunctionComponent<Props>=({ foo, children,}:Props)=>{return(<div>{foo}{children}</div>);// OK};// OK agora mas futuramente se tornará obsoletoconstVoidFunctionComponent:React.VoidFunctionComponent<Props>=({ foo, children,})=>{return(<div>{foo}{children}</div>);};
Na maioria dos casos, faz pouca diferença qual sintaxe é usada, mas você pode preferir a natureza mais explícita deReact.FunctionComponent.
Problemas menores
Esses padrões não são suportados:
** Renderização condicional **
constMyConditionalComponent=({ shouldRender=false})=>shouldRender ?<div/> :false;// tampouco faça isso em JSconstel=<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 ounull, caso contrário, ele reclama com uma mensagem de erro enigmática dizendo que outro tipo não pode ser atribuído ao Elemento.
constMyArrayComponent=()=>Array(5).fill(<div/>);constel2=<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:
constMyArrayComponent=()=>(Array(5).fill(<div/>)asany)asJSX.Element;
[Veja o comentário de @ferdaber aqui] (typescript-cheatsheets/react#57).
Há suporte para Hooks em@types/react a partir da versão v16.8.
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 (utilizandoUsing 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>({}asIUser);// mais adiante...setUser(newUser);
"Mentimos" temporariamente para o compilador de Typescript que{} é do tipoIUser. Você deve então configurar o estado deuser — se não o fizer, o resto do seu código pode depender do fato de queuser é do tipoIUser e isso pode levar a erros em tempo de execução (runtime errors).
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.
constinitialState={count:0};typeACTIONTYPE=|{type:"increment";payload:number}|{type:"decrement";payload:string};functionreducer(state:typeofinitialState,action:ACTIONTYPE){switch(action.type){case"increment":return{count:state.count+action.payload};case"decrement":return{count:state.count-Number(action.payload)};default:thrownewError();}}functionCounter(){const[state,dispatch]=React.useReducer(reducer,initialState);return(<> Count:{state.count}<buttononClick={()=>dispatch({type:"decrement",payload:"5"})}> -</button><buttononClick={()=>dispatch({type:"increment",payload:5})}> +</button></>);}
Uso do tipo `Reducer` da biblioteca `redux`
Caso você use a bibliotecaredux para escrever a reducer function, ela fornece um helper conveniente do formatoReducer<State, Action> que cuida do tipo do retorno para você.
Assim, o exemplo de reducer acima se torna:
import{Reducer}from'redux';exportfunctionreducer:Reducer<AppState,Action>(){}
AmbosuseEffect euseLayoutEffect são usados para executarefeitos 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 usaruseEffect, tome cuidado para não retornar nada além de uma função ouundefined, caso contrário, tanto o TypeScript quanto o React apresentarão error. Isso pode ser sutil ao usar arrow functions:
functionDelayedEffect(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 chavesreturnnull;}
Solução para o exemplo acima
functionDelayedEffect(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á undefinedreturnnull;}
Em TypeScript,useRef retorna uma referência que pode sersomente leitura oumutá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.
Para acessar um elemento da DOM: forneça apenas o tipo de elemento como argumento e usenull 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 à propref de um elemento:
functionFoo(){// - 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>constdivRef=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 elementoif(!divRef.current)throwError("divRef is not assigned");// Agora você tem certeza que divRef.current é um HTMLDivElementdoSomethingWith(divRef.current);});// Atribua a ref a um elemento para que o React possa gerenciar-lo pra vocêreturn<divref={divRef}>etc</div>;}
Se você tem certeza de quedivRef.current nunca será nulo, também é possível usar o operador de asserção não nulo!:
constdivRef=useRef<HTMLDivElement>(null!);// Mais tarde... não precisa checar se o elemento é nulodoSomethingWith(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 qualquerHTMLElement 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:
Para ter um valor mutável: forneça o tipo desejado e verifique se o valor inicial pertence totalmente a esse tipo:
functionFoo(){// Tecnicamente, isto retorna MutableRefObject<number | null>constintervalRef=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 elementoreturn<buttononClick={/* clearInterval the ref */}>Cancel timer</button>;}
Não temos muito ainda sobre esse tema,há uma discussão nas issues do repositório original. Por favor, contribua se puder!
typeListProps<ItemType>={items:ItemType[];innerRef?:React.Ref<{scrollToItem(item:ItemType):void}>;};functionList<ItemType>(props:ListProps<ItemType>){useImperativeHandle(props.innerRef,()=>({scrollToItem(){},}));returnnull;}
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, useconst assertions do TypeScript 3.4:
exportfunctionuseLoading(){const[isLoading,setState]=React.useState(false);constload=(aPromise:Promise<any>)=>{setState(true);returnaPromise.finally(()=>setState(false));};return[isLoading,load]asconst;// infere [boolean, typeof load] ao invés de (boolean | typeof load)[]}
Dessa forma, quando você desestrutura (desctructure), você obtém os tipos certos com base na posição de desestruturação.
Se você estátendo problemas com const assertions, você também pode declarar ou definir os tipos do retorno da função:
exportfunctionuseLoading(){const[isLoading,setState]=React.useState(false);constload=(aPromise:Promise<any>)=>{setState(true);returnaPromise.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:
functiontuplify<Textendsany[]>(...elements:T){returnelements;}functionuseArray(){constnumberValue=useRef(3).current;constfunctionValue=useRef(()=>{}).current;return[numberValue,functionValue];// o tipo fica (number | (() => void))[]}functionuseTuple(){constnumberValue=useRef(3).current;constfunctionValue=useRef(()=>{}).current;returntuplify(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.
- https://medium.com/@jrwebdev/react-hooks-in-typescript-88fce7001d0d
- https://fettblog.eu/typescript-react/hooks/#useref
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.
About
React Typescript Cheatsheet in Portuguese 🇧🇷
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Contributors5
Uh oh!
There was an error while loading.Please reload this page.

