O Styled Components é uma biblioteca de CSS-in-JS, ou seja, que nos permite estilizar os componentes utilizando a sintaxe da linguagem CSS de dentro do Javascript. Ele é muito utilizado com o React na web, mas também é possível utilizá-lo com o React Native para tornar a estilização ainda mais fácil, especialmente quando já possuímos conhecimento de CSS.

Nessa aula você irá aprender como utilizar o Styled Components para criar componentes estilizados de forma bem rápida.

  1. A primeira coisa que precisamos fazer é instalar a biblioteca no projeto. Vamos utilizar o projeto que temos construído durante todas as aulas e instalar o styled-components com o seguinte comando (podemos utilizar a instalação com yarn ou npm)

    yarn add styled-components
    
    npm install styled-components --save
    
  2. Agora que já temos ela instalada vamos criar um arquivo StyledContainer.js dentro da pasta “components”. Esse container será, a princípio, igual ao que criamos anteriormente, porém o construiremos utilizando styled-components. Fazemos isso utilizando “styled.” seguido do componente básico do React Native que estamos estilizando. O styled-components irá então criar para nós um componente estendendo este que escolhemos e acrescentando os estilos, que são escritos utilizando template strings do javascript e a sintaxe do CSS:

    Obs.: para uma melhor visualização do código você também pode instalar a extensão oficial vscode-styled-components no VS Code.

    import styled from 'styled-components/native'
    
    export default styled.View`
      flex: 1;
      margin: 32px 0 0;
      padding: 16px;
    `
    
  3. Vamos criar também um componente chamado StyledTitle.js também na pasta “components” para usarmos nos títulos:

    Obs.: repare que aqui nós usamos as medidas de px, exatamente como se estivéssemos escrevendo CSS.

    import styled from "styled-components/native";
    
    export default styled.Text`
      color: '#f64348';
      font-size: 40px;
    `
    
  4. Agora vamos criar uma nova tela StyledComponentsScreen.js na pasta “screens” para utilizar os novos componentes:

    import { useNavigation } from "@react-navigation/native";
    import StyledContainer from "../components/StyledContainer";
    import StyledTitle from "../components/StyledTitle";
    
    export default function StyledComponentsScreen() {
      return (
        <StyledContainer>
          <StyledTitle>Styled Components</StyledTitle>
        </StyledContainer>
      )
    }
    
  5. Vamos fazer o procedimento de sempre para incluir essa nova tela no nosso aplicativo, criando uma nova Stack.Screen no arquivo StackNavigator.js, depois adicionando um botão na tela HomeScreen que leva para a nova tela:

    // ...
    import ScrollViewScreen from "./screens/ScrollViewScreen"
    import StyledComponentsScreen from "./screens/StyledComponentsScreen"
    
    const Stack = createNativeStackNavigator()
    
    // ...
    
            <Stack.Screen name="ScrollView" component={ScrollViewScreen} />
            <Stack.Screen name="FlatList" component={FlatListScreen} />
            <Stack.Screen name="Styled" component={StyledComponentsScreen} />
          </Stack.Navigator>
        </NavigationContainer>
      )
    }
    
    // ...
    
      const toStyledComponentsScreen = () => {
        navigation.navigate('Styled')
      }
    
      return (
        <Container>
          <Title text="Olá, mundo!" />
          <StatusBar style="auto" />
          <NavButton text="Aula de Navegação" onPress={toNavigationScreen} />
          <NavButton text="Aula de ScrollView" onPress={toScrollViewScreen} />
          <NavButton text="Aula de FlatList" onPress={toFlatListScreen} />
          <NavButton text="Aula de Styled Components" onPress={toStyledComponentsScreen} />
        </Container>
      )
    }
    
  6. Com isso já podemos ver que nossa tela está funcionando perfeitamente, ou seja, criamos os mesmo componentes de antes, porém de forma muito mais fácil e rápida através do styled-components.

  7. Além de criar componentes estilizados, também podemos utilizar as vantagens do javascript e das props do React com o styled-components. Para demonstrar isso vamos modificar os nossos dois componentes StyledContainer e StyledTitle para que aceitem props que modifiquem a sua cor, assim teremos componentes mais customizáveis. Veja como é fácil fazer isso com o styled-components.

  8. Para incluir código javascript utilizamos a próprio sintaxe de ${ } das template strings, e para ter acesso às props usamos uma arrow function que tem elas como parâmetro e retornamos o resultado que queremos. Nesse caso, se a prop color existir ela será usada na estilização, se não usamos uma cor padrão branca:

    import styled from 'styled-components/native'
    
    export default styled.View`
      flex: 1;
      background-color: ${(props) => props.color ?? '#fff'};
      margin: 32px 0 0;
      padding: 16px;
    `
    
  9. Vamos fazer algo parecido para que o StyledTitle também aceite uma propriedade de cor:

    import styled from "styled-components/native";
    
    export default styled.Text`
      color: ${(props) => props.color ?? '#f64348'};
      font-size: 40px;
    `
    
  10. Agora em nossa tela StyledComponentsScreen podemos usar a propriedade color para definir a cor que quisermos para nossos componentes:

    import { useNavigation } from "@react-navigation/native";
    import StyledContainer from "../components/StyledContainer";
    import StyledTitle from "../components/StyledTitle";
    
    export default function StyledComponentsScreen() {
      return (
        <StyledContainer color="#f64348">
          <StyledTitle color="#1c1a1d">
            Styled Components
          </StyledTitle>
        </StyledContainer>
      )
    }
    
  11. Também podemos criar componentes mais elaborados utilizando vários styled-components. Crie um arquivo StyledButton.js na pasta “components” e adicione o seguinte código:

    Obs.: veja que criamos dois componentes com styled separadamente e os usamos em um componente de botão mais elaborado.

    Obs².: repare também que a propriedade onPress em Background é automaticamente entendida pois ele se trata de um TouchableOpacity, herdando suas props.

    import styled from "styled-components/native";
    
    const Background = styled.TouchableOpacity`
      background-color: ${({ color }) => color ?? '#1c1a1d'};
      border-radius: 10px;
      margin: 10px 0;
      padding: 10px;
    `
    
    const Text = styled.Text`
      color: ${({ color }) => color ?? '#fff'};
    `
    
    export default function({ bgColor, color, children, onPress }) {
      return (
        <Background color={bgColor} onPress={onPress}>
          <Text color={color}>
            {children}
          </Text>
        </Background>
      )
    }
    
  12. Agora podemos usar esse botão criado com styled-components na tela StyledComponentsScreen adicionando a funcionalidade de voltar para a tela anterior:

    import { useNavigation } from "@react-navigation/native";
    import StyledButton from "../components/StyledButton";
    import StyledContainer from "../components/StyledContainer";
    import StyledTitle from "../components/StyledTitle";
    
    export default function StyledComponentsScreen() {
      const navigation = useNavigation()
    
      const navigateBack = () => {
        navigation.goBack()
      }
    
      return (
        <StyledContainer color="#f64348">
          <StyledTitle color="#1c1a1d">
            Styled Components
          </StyledTitle>
          <StyledButton bgColor="#fff" color="#1c1a1d" onPress={navigateBack}>
            Voltar
          </StyledButton>
        </StyledContainer>
      )
    }