Implementando Shimmer Effect no React Native
Há algum tempo o Facebook criou uma forma inusitada para indicar o carregamento de suas páginas, o chamado Shimmer Effect, que nada mais é que a exibição de um esqueleto da página em forma de animação no lugar de um Spinner ou uma Barra de Progresso, no React Native utilizaremos o react-native-shimmer-placeholder que dará uma melhora tanto no Design quanto na Usabilidade do nosso app.
O Shimmer Effect é uma alternativa muito efetiva em relação ao loading tradicional pois permite que sejam criadas Skeletons Screens, que são as páginas onde enquanto o conteúdo é carregado de modo assíncrono o Shimmer está aparecendo, e ele dá um feedback bacana para o usuário, trazendo as seguintes vantagens:
- Faz com que o usuário perceba que a página/tela carrega rápido;
- Acaba com a surpresa sobre a interface;
- Carregamento gradual da interface;
- Indicação clara de progresso;
- Mostra exatamente o que já foi carregado e o que ainda tem para carregar.
E nesse post vou te mostrar como implementar esse efeito fantástico no seu aplicativo para melhorar a experiência para o usuário final, algumas empresas famosas que utilizam essa técnica são o Google, Facebook, Medium e Instagram.
Então chega de papo e vamos à criação do projeto \o/
Criando o projeto React Native
Para iniciar o projeto você pode utilizar o React Native CLI, com ele instalado basta executar o comando:
react-native init ShimmerPlaceholder
Com o projeto criado instale o react-native-shimmer-placeholder e também uma dependência dele que precisa ser instalada manualmente, a react-native-linear-gradient:
yarn add react-native-linear-gradient
yarn add react-native-shimmer-placeholder
// npm install react-native-linear-gradient
// npm install react-native-shimmer-placeholder
E como o Linear Gradient utiliza de recursos nativos do dispositivo tem que ser feito o link entre o Javascript e o Código Nativo, e para isso basta executar:
react-native link react-native-linear-gradient
Nesse ponto você já está com sua aplicação pré-configurada e pronta para usar o Shimmer Effect, caso você tenha algum problema com a criação ou instalação dos pacotes, pode consultar a estrutura inicial nesse link.
Aplicando o Shimmer Placeholder
Antes de começarmos com o código em React Native, caso você ainda não conheça o framework, ou quer reforçar seus conhecimentos em Javascripte ES6/ES7/ ES8, dê uma olhada nos nossos minicursos gratuitos.
Será utilizado como referência a estrutura da página do Facebook, como essa abaixo:
Para focar apenas no uso da lib não serão os componentes da Barra de Busca e do TabMenu na parte inferior, para criar a estrutura inicial da página pronta para receber o conteúdo com o Shimmer Effect será editado o conteúdo do App.js
, deixando-o da seguinte maneira:
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.searchBar} />
<View style={styles.content}></View>
<View style={styles.menuBar} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5FCFF',
},
searchBar: {
height: 54,
backgroundColor: '#3b5998',
},
content: {
flex: 1,
},
menuBar: {
height: 54,
backgroundColor: '#edeef1',
}
});
Agora sim serão criadas as funções responsáveis por criar o esqueleto da página.
O primeiro passo é importar o react-native-shimmer-placeholder no começo do código, para isso basta importar ele dessa maneira:
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
Com ele importado você pode criar o state que irá conter 3 variáveis booleanas que serão as responsáveis por dizer ao código quando deve ser renderizado o efeito ou o conteúdo devido da página, você pode criá-lo entre a declaração da classe do componente e o método render, o state ficou assim:
state = {
visible: false,
userImageVisible: false,
postImageVisible: false,
}
Foram criadas 2 variáveis para as imagens pois será adotada uma abordagem diferente no carregamento delas, ao invés de serem exibidas junto com o conteúdo elas serão exibidas assim que forem carregadas.
Quer ver mais sobre o que você pode fazer com imagens na sua aplicação para melhorar a usabilidade? Corre lá dar uma olhada nesse post do Diego sobre Lazy Loading 😉
O próximo passo é criar o render do componente, para modularizar um pouco retirei a renderização dos componentes do método render e passei para uma função, portanto o render ficou assim:
render() {
return (
<View style={styles.container}>
<View style={styles.searchBar} />
{ this.renderRows(3) }
<View style={styles.menuBar} />
</View>
);
}
E como o estilo ficou um pouco extenso, para não postá-lo e apenas estender o post deixei ele disponível nesse link para vocês estilizarem a aplicação, basta copiar o código do link e inserir na const styles
no final do componente App
.
Antes de ir para a última parte (finalmente), a função que foi criada, a renderRows, será a responsável por retornar toda a estrutura da página, e o número passado para ela como parâmetro é a quantidade de componentes que ela vai renderizar, no nosso caso foi passado 3 para que ela renderize 3 posts.
E sobre a implementação da função renderRows, assim como o estilo ficou bastante extensa, e é por isso que disponibilizei ela nesse link, para inseri-la no nosso componente basta copiar o código do link e inseri-lo entre o state e o método render
do componente App
, abaixo darei uma breve explicação do funcionamento dela e do uso do componente ShimmerPlaceholder.
No começo da função há um laço de repetição para garantir que serão criados os componentes de acordo com o número passado por parâmetro, e dentro desse laço você verá em vários lugares o seguinte código:
<ShimmerPlaceHolder
style={styles.shimmerComponent}
autoRun={true}
visible={this.state.visible}
>
<Text></Text>
</ShimmerPlaceHolder>
Esse é o componente disponibilizado pela lib react-native-shimmer-placeholder para criar o efeito de carregamento, as props que foram usadas são a autoRun, que indica que assim que o componente for instanciado o efeito será iniciado, e a visible, que indica se o que será mostrado é a animação do componente ou o conteúdo de fato. Para ver todas as props disponíveis você pode acessar esse link.
E a última coisa a se fazer é inserir dentro do componentDidMount uma função para testar o funcionamento, pois enquanto os states estiverem com o valor false somente o efeito será mostrado, para isso você pode criar uma função para mudar esse valor depois de 2,5 segundos, ficando assim:
componentDidMount() {
setTimeout(() => this.setState({ visible: !this.state.visible }), 2500);
}
Com tudo isso feito basta rodar o projeto e voilà, tudo deve estar funcionando corretamente.
Caso você tenha algum problema, dúvida ou seu projeto não esteja funcionando corretamente você pode acessar o código completo nesse link e comparar com o seu 😉
Conclusão
E chegamos ao final de mais um post, e nesse post mostrei uma alternativa ao Spinner que vem ganhando bastante espaço no desenvolvimento de aplicativos e sistemas web por proporcionar uma usabilidade e design mais agradável ao usuário.
Se você chegou até aqui desce mais um pouquinho e deixa seu comentário de sugestão ou crítica sobre o post 😉 É através do seu feedback que podemos cada vez melhorar mais e mais.
E por hoje é isso, um abraço!