Uma das práticas mais utilizadas por quem está começando a criar projetos em React Native é definir os estilos no mesmo arquivo que o componente ou no máximo separar a parte apresentável da lógica, mais ou menos da seguinte forma:

export default class MyComponent extends Component {
  render() {
    return (
      <View style={styles.container} />
    );
  }
}

const styles = StyleSheet.create({
  container: {
    // My styles
  },
});

O principal problema dessa forma está em utilizar a variável de estilos mesmo antes de ser definida. Se você utilizar o ESLint, provavelmente vai ser um erro que ele vai apontar. “Ah, mas é só passar pra cima do componente”, sim, mas então assim que você abre o componente, a primeira coisa que você vê são os estilos… Acho que não é a melhor forma.

Nesse post vamos entender duas práticas para organização dos estilos dos componentes. Inclusive as duas devem ser usadas juntas e você não deve escolher uma delas.

Utilizando arquivo externo

A primeira maneira de melhorar todo esse processo é separar o arquivo de estilos do componente da seguinte forma:

Desse modo, a organização dos arquivos já fica bem melhor e você não precisa mudar suas importações, por exemplo: import Header from 'components/Header'; irá continuar igual.

Dessa forma, o componente criado ficaria dessa forma:

const styles = StyleSheet.create({
  container: {
    // My styles
  },
});

export default styles;
import styles from './styles';

export default class MyComponent extends Component {
  render() {
    return (
      <View style={styles.container} />
    );
  }
}

Separando estilos genéricos

O que é comum de toda aplicação, tanto web quando mobile, é geralmente seguir um padrão de cores, espaçamentos, fontes, etc. Nesses casos o mais correto é separar esses estilos genéricos em uma pasta alternativa.

Hoje nos meus projetos eu crio uma pasta na raiz (geralmente chamo de src) chamada styles e essa pasta fica responsável por armazenar qualquer estilo que eu irei utilizar em mais lugares do meu projeto, evitando redundâncias.

Dentro dessa pasta eu tenho os seguintes arquivos:


// src/styles/index.js

import colors from './colors';
import fonts from './fonts';
import metrics from './metrics';
import general from './general';

export { colors, fonts, metrics, general };

index.js: Importa os arquivos de estilo e exporta de forma com que você consiga importar um ou vários arquivos com o mesmo import.

// src/styles/colors.js

const colors = {
  header: '#333333',
  primary: '#069',
};

export default colors;

colors.js: Responsável por armazenar as cores utilizadas na aplicação, e aqui vai desde cores para layouts como cores do TextInput, textos em geral, botões, etc.

// src/styles/fonts.js

const fonts = {
  input: 16,
  regular: 14,
  medium: 12,
  small: 11,
  tiny: 10,
};

export default fonts;

fonts.js: Aqui é onde armazeno os tamanhos de fontes utilizadas no projeto, então, assim como no colors, todos tamanhos de fontes devem possuir algum significado e por isso estão nesse arquivo.

// src/styles/metrics.js

import { Dimensions, Platform } from 'react-native';

const { width, height } = Dimensions.get('window');

const metrics = {
  smallMargin: 5,
  baseMargin: 10,
  doubleBaseMargin: 20,
  screenWidth: width < height ? width : height,
  screenHeight: width < height ? height : width,
  tabBarHeight: 54,
  navBarHeight: (Platform.OS === 'ios') ? 64 : 54,
  statusBarHeight: (Platform.OS === 'ios') ? 20 : 0,
  baseRadius: 3,
};

export default metrics;

metrics.js: Margens, paddings, tamanhos configurados pela plataforma (ex.: StatusBar), Border Radius, etc. Tudo que está ligado diretamente com espaçamento e ocupação de um componente em tela vai nesse arquivo.

// src/styles/general.js

import metrics from './metrics';
import colors from './colors';
import fonts from './fonts';

const general = {
  container: {
    flex: 1,
    backgroundColor: colors.background,
  },
  section: {
    margin: metrics.doubleBaseMargin,
  },
  sectionTitle: {
    color: colors.text,
    fontWeight: 'bold',
    fontSize: fonts.regular,
    alignSelf: 'center',
    marginBottom: metrics.doubleBaseMargin,
  },
};

export default general;

general.js: O arquivo general é o único diferente dos demais. Seu papel não é armazenar variáveis, mas sim armazenar estilos de componentes padrão. Pense que em seu aplicativo você possui um layout de seção que aplica um espaçamento e possui um título em negrito.

Ao invés de criar um componente chamado Section você apenas importa os estilos do general.js no seu arquivo styles.js e sai usando as propriedades section e secionTitle. A importação pode ser realizada da seguinte forma:

import { StyleSheet } from 'react-native';
import { general } from 'styles';

const styles = StyleSheet.create({
  ...general,
});

export default styles;

A partir desse momento, no seu componente você poderá utilizar todas as propriedades definidas no arquivo general.js.

Chegando ao fim

Nesse post apresentei duas formas de melhorar a organização dos estilos dentro do React Native e agora quero saber de você, como anda organizando sua estrutura? Utiliza algum pacote terceiro para te ajudar nesse processo? Deixa aí nos comentários.