A maioria dos projetos que utilizam React para construir o front-end de sua aplicação, empregam bibliotecas para organizar e agilizar o trabalho. Para organização de estilos, a biblioteca mais popular é styled components e neste artigo vamos mostrar uma refatoração implementando componentes para substituir CSS puro.
Como seguir esse tutorial!!
Para acompanhar, vá editando o template: https://codesandbox.io/s/styled-components-v2-m6oc7
Explicando o exemplo
Nosso objetivo é refatorar o componente Navigation
de uma landing page da Campus Code, utilizando styled components
.
Esse componente está localizado em src/Navigation/index.js
e seus estilos em src/Navigation/styles.css
.
Adicionando dependências
Antes de começar, precisamos adicionar a dependência Styled Components.
No codesandbox podemos adicioná-la na aba dependencies, conforme a imagem:
Em um projeto local, adicionaríamos com npm
ou yarn
:
npm install --save styled-components
yarn add styled-components
O que vamos refatorar
Analisando nosso componente, vemos que a seguinte estrutura se repete 4 vezes:
<a
className="navlink"
href="*url*"
target="_blank"
rel="noopener noreferrer"
>
*texto*
</a>
Também podemos aproveitar para transformar nossa div.navcontainer
em um elemento de estilo:
<div className="navcontainer">
Como vamos refatorar
Para organizar nossos componentes de estilos, vamos criar um arquivo src/Navigation/styles.js
e transferir os estilos de src/Navigation/styles.css
para ele.
Depois, vamos passar esses componentes de estilo para nosso componente Navigation
.
Removendo CSS puro
Antes de começar, vamos remover a linha import "./styles.css";
em src/Navigation/index.js
.
Nossa aplicação deve ficar assim:
Refatorando
Vamos criar o arquivo src/Navigation/styles.js
.
Nele, vamos importar styled dos styled-components
que nos permitirá a criação de componentes de estilo.
Depois vamos criar dois componentes de estilo Link
e NavContainer
:
/* styles.js */
import styled from "styled-components"
export const NavContainer = styled.div``;
export const Link = styled.a``;
Em NavContainer
, copiaremos os estilos da classe .navcontainer
de src/Navigation/styles.css
.
Em Link
, copiaremos os estilos da classe .navlink
.
Como com styled components podemos utilizar seletores Sass
, também conseguimos passar o hover
para dentro do nosso componente.
/* styles.js */
import styled from "styled-components"
export const NavContainer = styled.div`
display: flex;
flex-direction: column;
`;
export const Link = styled.a`
margin-top: 32px;
background-color: #47e500;
text-decoration: none;
font-family: ArchiaBold;
letter-spacing: 0.2rem;
color: #000;
transition: 0.3s;
font-weight: 600;
border-radius: 0;
line-height: 1.5;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: min(4vw, 1.2rem);
line-height: 1.5;
border-radius: 0.25rem;
width: min(60vw, 400px);
max-width: 300px;
cursor: pointer;
outline: none;
&:hover {
background-color: #ff3095;
}
`;
Agora que já passamos nossos estilos para styles.js
, podemos apagar o arquivo styles.css
.
Passando nossos componentes de estilo para Navigation
Vamos importar nossos componentes em src/Navigation/index.js
e fazer a substituição.
Trocaremos:
```html
<a className="navlink" href="url" target="_blank" rel="noopener noreferrer"
*texto*
```
Para:
<NavContainer>
</NavContainer>
<Link
href="*url*"
target="_blank"
rel="noopener noreferrer"
>
*texto*
</Link>
Nosso componente ficará assim:
import React from "react";
import { Link, NavContainer } from "./styles.js";
export default function Navigation() {
return (
<NavContainer>
<Link
href="<https://www.campuscode.com.br/conteudos>"
target="_blank"
rel="noopener noreferrer"
>
conteúdos
</Link>
<Link
href="<https://www.campuscode.com.br/treinamentos>"
target="_blank"
rel="noopener noreferrer"
>
treinamentos
</Link>
<Link
href="<https://www.campuscode.com.br/para_empresas>"
target="_blank"
rel="noopener noreferrer"
>
para empresas
</Link>
<Link
href="<https://www.campuscode.com.br/contacts/new>"
target="_blank"
rel="noopener noreferrer"
>
contato
</Link>
</NavContainer>
);
}
Agora, nossa aplicação deve estar devidamente estilizada, como quando começamos.
Adicionando atributos para componentes de estilo
Ainda podemos melhorar esse componente removendo a repetição dos atributos:
target="_blank"
rel="noopener noreferrer"
Para isso, podemos nos aproveitar do método attrs
do styled components, adicionando esses atributos no nosso componente Link
:
/* styles.js */
export const Link = styled.a.attrs(() => ({
target: "_blank",
rel: "noopener noreferrer"
}))`
margin-top: 32px;
background-color: #47e500;
text-decoration: none;
...
`
Dessa forma, conseguimos reduzir ainda mais nosso componente:
/* index.js */
import React from "react";
import { Link, NavContainer } from "./styles.js";
export default function Navigation() {
return (
<NavContainer>
<Link href="<https://www.campuscode.com.br/conteudos>">
conteúdos
</Link>
<Link href="<https://www.campuscode.com.br/treinamentos>">
treinamentos
</Link>
<Link href="<https://www.campuscode.com.br/para_empresas>">
para empresas
</Link>
<Link href="<https://www.campuscode.com.br/contacts/new>">
contato
</Link>
</NavContainer>
);
}
Passando props para componentes de estilo
No nosso código ainda temos a repetição da url https://www.campuscode.com.br/
, então para evitar isso vamos passar a prop to
indicando que queremos acessar um caminho dessa url:
/* styles.js */
export const Link = styled.a.attrs(props => ({
target: "_blank",
rel: "noopener noreferrer"
href: `https://www.campuscode.com.br/${props.to}`
}))`
margin-top: 32px;
background-color: #47e500;
text-decoration: none;
...
`
E no nosso componente:
/* index.js */
import React from "react";
import { Link, NavContainer } from "./styles.js";
export default function Navigation() {
return (
<NavContainer>
<Link to="conteudos">conteúdos</Link>
<Link to="treinamentos">treinamentos</Link>
<Link to="para_empresas">para empresas</Link>
<Link to="contacts/new">contato</Link>
</NavContainer>
);
}
Assim, a nossa aplicação fica bem mais organizada numa estrutura de pastas com cada coisa em seu lugar. Isso torna também nossos componentes mais fáceis de serem reutilizados, na mesma ou em outras aplicações!