React Native: Utilizando styled-components

Natalia Kelim Thiel
Natalia Kelim Thiel

Compartilhe

Avalie este artigo

10 minutos de leitura

Chegou aquele momento em que você quer criar um app inspirado em uma aplicação web, ou simplesmente quer adotar um padrão de estilos mais fácil de manter e organizar, sem deixar propriedades style espalhadas por cada componente do projeto. 

É aí que entra a biblioteca styled-components. Com ela, você escreve estilos em um formato muito próximo do CSS e cria componentes já com seus estilos encapsulados, mantendo o código limpo e bem organizado.

Mas como aplicar tudo isso em um projeto React Native? É exatamente isso que vamos explorar ao longo deste artigo. 

O Projeto Base 

Para exemplificar, vamos usar a tela de um rosto que lembra o personagem Pikachu, que originalmente foi desenvolvida com a forma padrão de estilos do React Native. Fique à vontade para clonar o projeto  ou criar um componente do zero para acompanhar o raciocínio. 

Tela da aplicação contendo um fundo amarelo e elementos de um rosto que lembram o personagem Pikachu 
Banner promocional da Alura destacando até 35% de desconto em cursos de tecnologia. A mensagem reforça que a diferença entre potencial e resultado está no preparo, incentivando profissionais a se anteciparem às mudanças do mercado e investirem no desenvolvimento de novas habilidades. A imagem mostra uma pessoa usando fones de ouvido e há um botão com a chamada "Aproveitar agora" para começar a evoluir na carreira tech.

Primeiros passos com styled-components 

Vamos começar a transformar nossos estilos em styled-components pela boca. Mas, calma lá, não estamos esquecendo algo? Sim, falta instalar a biblioteca!  

Para isso, executamos o seguinte comando, dentro da pasta do projeto, e ainda temos que rodar o projeto novamente: 

# com npm
npm install styled-components
# com yarn
yarn add styled-components 

Agora que o pacote está pronto para uso, vamos comparar a estrutura antiga com o novo formato. 

O Modelo tradicional 

Antes, dividíamos o componente em dois arquivos. Um para a estrutura e outro para a estilização com StyleSheet

Antigo src/Pikachu/Boca/index.js 

import React from 'react'; 
import { View } from 'react-native'; 
import estilos from './estilos'; 
export default function Boca() { 
return <View style={estilos.boca} /> 
}

Antigo src/Pikachu/Boca/estilos.js 

import { StyleSheet } from 'react-native'; 
export default StyleSheet.create({ 
boca: { 
     width: 85, 
     height: 60, 
     marginTop: -30, 
     backgroundColor: "#F18061", 
     borderWidth: 3, 
     borderColor: "#7B2B09", 
     borderTopStartRadius: 40, 
     borderTopEndRadius: 25, 
     borderBottomEndRadius: 30, 
     borderBottomStartRadius: 60, 
} 
});

O Modelo estilizado 

Com o Styled Components, unificamos tudo em apenas um arquivo, deixando o código limpo: 

Novo src/Pikachu/Boca/index.js 

import styled from 'styled-components'; 
const Boca = styled.View` 
width: 85px; 
height: 60px; 
margin-top: -30px; 
background-color: #F18061; 
border: 3px solid #7B2B09; 
border-top-start-radius: 40px; 
border-top-end-radius: 25px; 
border-bottom-end-radius: 30px; 
border-bottom-start-radius: 60px; 
`; 
export default Boca;

No exemplo, importamos os styled-components na variável styled e usamos o objeto View dentro dele para criarmos um componente do tipo view customizado.

No lugar da View poderíamos usar qualquer outro componente React Native. Então colocamos nosso “CSS” dentro de crases. Mas temos que fazer algumas mudanças em relação aos estilos normais, que são: 

  • Mudar as vírgulas por ponto e vírgulas ;
  • Adicionar as unidades px após os números 
  • Remover as aspas dos hexadecimais de cor. 
  • Trocar a nomenclatura adicionando o traço em vez da primeira letra maiúscula. 
  • Não é obrigatório, mas podemos também reescrever borderWidth e borderColor em uma propriedade unificada border.

Agora, vamos fazer o mesmo com o nariz e as bochechas. Como eles também são componentes View estilizados, podemos apenas retornar seus respectivos index, não sendo necessário mais um arquivo de estilos.  

Para o nariz, basta converter da mesma forma que fizemos antes, de estilos.js para index.js

Antigo src/Pikachu/Nariz/estilos.js 

import { StyleSheet } from 'react-native'; 
export default StyleSheet.create({ 
nariz: { 
     width: 25, 
     height: 20, 
     backgroundColor: "#000200", 
     borderTopStartRadius: 10, 
     borderTopEndRadius: 10, 
     borderBottomStartRadius: 30, 
     borderBottomEndRadius: 30, 
} 
});

Novo src/Pikachu/Nariz/index.js 

import styled from 'styled-components'; 
const Nariz = styled.View` 
width: 25px; 
height: 20px; 
backgroundColor: #000200; 
border-top-start-radius: 10px; 
border-top-end-radius: 10px; 
border-bottom-start-radius: 30px; 
border-bottom-end-radius: 30px; 
`; 
export default Nariz;

Já com as bochechas, temos uma propriedade diferente: a transform. Nos estilos com React Native, temos de usar esse formato não tão interessante de array com objeto. Com styled-components, já podemos fazer em forma de CSS mesmo, veja abaixo. 

Antigo src/Pikachu/Bochecha/estilos.js 

import { StyleSheet } from 'react-native'; 
export default StyleSheet.create({ 
bochecha: { 
     width: 70, 
     height: 70, 
     backgroundColor: "#E15B42", 
     borderRadius: 35, 
     transform: [{scaleX: 1.2}] 
} 
});

Novo src/Pikachu/Bochecha/index.js 

import styled from 'styled-components'; 
const Bochecha = styled.View` 
width: 70px; 
height: 70px; 
backgroundColor: #E15B42; 
border-radius: 35px; 
transform: scaleX(1.2); 
`; 
export default Bochecha;

Como funciona a herança de estilos 

Agora vamos incrementar um pouco as coisas, pois nos olhos temos dois componentes View e estilos externos sendo aplicados.  

Os estilos servem para fazer o espelhamento horizontal do olho direito e conseguirmos os dois brilhinhos na parte central do rosto. 

Antigo src/Pikachu/Olho/index.js 

import React from 'react'; 
import { View } from 'react-native'; 
import estilos from './estilos' 
export default function Olho({ estilosExtra }) { 
return <View style={[estilos.olho, estilosExtra]} > 
     <View style={estilos.brilho} /> 
</View> 
}

Mas vamos primeiro olhar para a estrutura do componente. 

Como temos a View interna, não podemos retornar apenas a view estilizada como temos feito. Precisamos manter essa estrutura e estilizar as duas Views. Então, neste caso, nosso estilos.js continuará existindo, porém, podemos mudar para a estrutura dos styled-components e retornar mais componentes estilizados. 

Antigo src/Pikachu/Olho/estilos.js 

import { StyleSheet } from 'react-native'; 
export default StyleSheet.create({ 
olho: { 
     backgroundColor: "#000200", 
     width: 55, 
     height: 55, 
     borderRadius: 28, 
}, 
brilho: { 
     backgroundColor: "#FEFEFE", 
     width: 20, 
     height: 20, 
     borderRadius: 10, 
     marginTop: 8, 
     marginLeft: 27, 
} 
});

Novo src/Pikachu/Olho/estilos.js 

import styled from 'styled-components'; 
export const OlhoExterno = styled.View` 
background-color: #000200; 
width: 55px; 
height: 55px; 
border-radius: 28px; 
`; 
export const Brilho = styled.View` 
background-color: #FEFEFE; 
width: 20px; 
height: 20px; 
border-radius: 10px; 
margin: 8px 0 0 27px; 
`;

Assim também simplificamos as margens em apenas uma linha de margin, como em CSS, e renomeamos o olho para OlhoExterno, pois Olho já é o nome do nosso componente principal.  

No entanto, se apenas salvarmos esta alteração, um erro pode surgir. Isso acontece porque ainda é necessário modificar o index.js para utilizar os novos componentes criados com styled-components

Novo src/Pikachu/Olho/index.js 

import React from 'react'; 
import { OlhoExterno, Brilho } from './estilos' 
export default function Olho({ estilosExtra }) { 
return <OlhoExterno style={estilosExtra} > 
     <Brilho /> 
</OlhoExterno> 
}

Caso surja a dúvida sobre como aplicar styled-components em aplicações já grandes, a dica é realizar a migração gradualmente, convertendo aos poucos os componentes, conforme for conveniente. 

Nesse exemplo do olho, estamos recebendo ainda os estilos padrão do React Native, e eles ainda funcionam. Mas como essa aplicação é mais simples, vamos transformar até os estilosExternos em styled-components. 

Para isso, utilizamos a herança de componentes. Ao analisar os arquivos principais index.js e estilos.js, observa-se que o segundo olho é chamado usando um estilo específico. 

Olhos em src/Pikachu/index.js 

<View style={estilos.olhos}> 
     <Olho /> 
<Olho estilosExtra={estilos.olhoDireito} /> 
</View>

Estilos dos olhos em src/Pikachu/estilos.js 

olhoDireito: { 
     transform: [{scaleX: -1}], 
},

Podemos criar um novo componente para o segundo olho que herda o componente de olho original (usando styled-components), facilitando assim a reutilização e personalização. O estilo antigo olhoDireito dos estilos React Native pode ser removido. 

Novos estilos em src/Pikachu/estilos.js 

import { StyleSheet } from 'react-native'; 
// Início do código novo 
import styled from 'styled-components'; 
import Olho from './Olho'; 
export const OlhoDireito = styled(Olho)` 
transform: scaleX(-1); 
`; 
// Fim do código novo 
export default StyleSheet.create({ 
...

Passando dessa forma um outro componente ou styled-component para a função styled, podemos criar um novo styled-component que herda a estrutura e os estilos dele. Então, podemos usar nosso novo componente que herda Olho e o inverte no index.js

Novo olho em src/Pikachu/index.js 

... 
import estilos, { OlhoDireito } from './estilos'; 
… 
<View style={estilos.olhos}> 
     <Olho /> 
     <OlhoDireito /> 
</View> 
…

Após salvar as alterações, caso os olhos não fiquem como esperado (ou seja, ambos apareçam iguais e não invertidos), é sinal de que a herança entre componentes não funcionou corretamente. 

Isso acontece porque o Olho é um componente criado da forma tradicional no React Native, que usa styled-components dentro dele. 

Portanto, precisamos permitir que os nossos styled-components internos recebam as alterações do nosso OlhoDireito. Caso estivéssemos tentando aplicar herança na boca, por exemplo, não teríamos este problema, pois a boca já é um styled-component. 

Permitindo herança no src/Pikachu/Olho/index.js 

import React from 'react'; 
import { OlhoExterno, Brilho } from './estilos' 
export default function Olho({ style }) { 
return <OlhoExterno style={style} > 
     <Brilho /> 
</OlhoExterno> 
}

Agora, passando a propriedade style para o OlhoExterno, podemos rodar nossa aplicação e a herança funciona. Também finalizamos a aplicação dos styled-components no Olho

Acesso dinâmico às propriedades (props) 

A estrutura da orelha é composta por um triângulo e um círculo que cobre parte do triângulo, fazendo o efeito de arredondamento no lado inferior. 

Na implementação das orelhas, a inversão é feita de forma diferente: a propriedade direita é passada ao componente, que realiza a inversão de forma interna. 

Antigo src/Pikachu/Orelha/index.js 

import React from 'react'; 
import { View } from 'react-native'; 
import funcaoEstilos from './estilos'; 
export default function Orelha({ direita = false }) { 
const estilos = funcaoEstilos(direita); 
return <View style={estilos.orelha}> 
     <View style={estilos.ponta} /> 
     <View style={estilos.marca} /> 
</View> 
}

Então, utilizamos nos estilos uma função para pegar este valor e retornar o StyleSheet correspondente. 

Antigo src/Pikachu/Orelha/estilos.js 

import { StyleSheet } from 'react-native'; 
export default function (direita) { 
return StyleSheet.create({ 
     orelha: { 
     transform: [{rotate: direita ? "5deg" : "-5deg" }, {scaleX: direita ? -1 : 1 }] 
     }, 
     ponta: { 
     width: 0, 
     height: 0, 
        backgroundColor: "transparent", 
        borderStyle: "solid", 
        borderRightWidth: 120, 
        borderTopWidth: 75, 
        borderRightColor: "transparent", 
        borderTopColor: "#000200", 
     transform: [{rotate: "270deg"}] 
     }, 
     marca: { 
     width: 135, 
     height: 135, 
        marginTop: -50, 
        marginLeft: 23, 
        backgroundColor: "#FCD458", 
        borderRadius: 77, 
     } 
}); 
}

Ao migrar para styled-components, a estrutura para acessar as propriedades se torna mais simples e intuitiva. 

Novo src/Pikachu/Orelha/estilos.js 

import styled from 'styled-components'; 
export const OrelhaExterna = styled.View` 
transform: rotate(-5deg) scaleX(${({ direita }) => direita ? -1 : 1}); 
`; 
export const Ponta = styled.View` 
width: 0; 
height: 0; 
background-color: transparent; 
border-style: solid; 
border-right-width: 120px; 
border-top-width: 75px; 
border-right-color: transparent; 
border-top-color: #000200; 
transform: rotate(270deg); 
`; 
export const Marca = styled.View` 
width: 135px; 
height: 135px; 
margin: -50px 0 0 23px; 
border-radius: 77px; 
background-color: #FCD458; 
`;

No exemplo acima, aplicamos a desestruturação diretamente nos argumentos da função (({ direita })) para coletar o valor booleano sem precisar digitar props.direita repetidas vezes. 

Há um detalhe técnico sutil no comportamento do transform aqui: invertemos a ordem declarativa colocando o rotate antes do scaleX.

Isso ocorre porque a engine do Styled Components faz a leitura e o processamento dessas transformações de trás para frente. Fique de olho nisso quando trabalhar com rotações acumuladas! 

Agora um desafio: 

Agora que você domina a base do encapsulamento de estilos, que tal colocar a mão na massa? 

Se você já acompanhou até aqui e quer treinar um pouco mais, você pode começar por aplicar styled-components no componente Pikachu que ficou faltando. Caso tenha perdido alguma coisa até aqui, você encontra o projeto neste ponto na branch styled

E para acessar o projeto finalizado com todos os estilos utilizando styled-components, você pode baixá-lo na branch completo

Vantagens de usar styled-components react native em seus projetos

Neste artigo você pôde aprender os conceitos básicos de styled-components, transformar estilos padrão em styled-components, utilizar herança e acessar propriedades.

Além, é claro, de poder baixar um modelo de Pikachu feito apenas com estilos. Também vimos algumas características que diferem os estilos padrão dos styled-components e do CSS, quando aplicado no React.  

Ficou com vontade de ver o seu código rodando direto no celular? Você pode aprender a criar projetos completos com Expo, integrar recursos nativos do aparelho e dominar o desenvolvimento multiplataforma. 

Acesse a lista de cursos de React Native na Alura e escolha o seu próximo passo nos estudos. 

Até mais! 

Avalie este artigo

Natalia Kelim Thiel
Natalia Kelim Thiel

Natalia é programadora e instrutora. Se apaixonou pela programação a primeira vista em 2013 e desde então vem trabalhando em diversas tecnologias no front-end, back-end, mobile e games.

Veja outros artigos sobre Mobile

Estude 2 anos por R$ 158/mês. Planos com até 35% OFF. Ver planos.