Guia Prático: Componente para exibir avaliações ⭐️⭐️⭐️⭐️⭐️
Recentemente, precisei criar um componente para exibir notas de 0.1 a 5.0, como no Uber e outros aplicativos de serviço. Em vez de usar uma biblioteca pronta, decidi criar nosso próprio componente.
Desenvolver um componente personalizado nos dá mais controle sobre sua aparência e comportamento, além de ser uma ótima chance de entender os sistemas de classificação por estrelas.
Neste artigo, vou mostrar como criar um componente de classificação por estrelas usando React Native e TypeScript. Esse componente recebe uma nota entre 0.1 e 5.0, representando-a com estrelas cheias, meias estrelas e estrelas vazias.
Embora focado em React Native, a lógica e os conceitos podem ser adaptados para outros frameworks e linguagens. Criar um sistema de classificação visual é comum e pode ser implementado de forma similar em ReactJS, Angular, Vue.js, entre outros.
Então, vamos lá!
Passo 1: Garantindo um Valor Máximo
Para começar, precisamos garantir que a nota recebida (data) não ultrapasse o valor máximo permitido de 5. Isso é feito utilizando a função Math.min()
, que retorna o menor valor entre os argumentos fornecidos.
const limitedRating = Math.min(data, 5);
Neste trecho de código, se data
for maior que 5, limitedRating
será definido como 5. Caso contrário, ele será igual a data
.
Passo 2: Separando a Parte Inteira e Decimal
Precisamos agora isolar a parte inteira da nota. Para isso, utilizamos a função Math.floor()
, que arredonda o valor para baixo.
const integerRating = Math.floor(limitedRating);
Se, por exemplo, limitedRating
for 3.5, integerRating
será igual a 3.
Em seguida, isolamos a parte decimal subtraindo a parte inteira de limitedRating
:
const decimalRating = limitedRating - integerRating;
Continuando com o exemplo anterior, se limitedRating
for 3.5, decimalRating
será 0.5.
Passo 3: Calculando o Número de Estrelas
Para representar a nota visualmente, usaremos três tipos de estrelas: cheias, meias e vazias.
Estrelas Cheias: O número de estrelas cheias será igual à parte inteira da nota.
const fullStars = integerRating;
Meia Estrela: Se a parte decimal for maior ou igual a 0.1, teremos uma meia estrela.
const halfStar = decimalRating >= 0.1;
Estrelas Vazias: O número de estrelas vazias será calculado subtraindo o número de estrelas cheias e, se houver, a meia estrela do total de 5 estrelas.
const emptyStars = 5 - fullStars - (halfStar ? 1 : 0);
Passo 4: Criando os Elementos de Estrela
Vamos agora criar os arrays de elementos JSX para cada tipo de estrela.
Estrelas Cheias:
const fullStarsElements = Array.from({ length: fullStars }, (_, index) => (
<FontAwesome key={index} name="star" size={14} color="#FCA311" />
));
Meia Estrela:
const halfStarElement = halfStar ? (
<FontAwesome name="star-half-full" size={14} color="#FCA311" />
) : null;
Estrelas Vazias:
const emptyStarsElements = Array.from({ length: emptyStars }, (_, index) => (
<FontAwesome key={index} name="star-o" size={14} color="#FCA311" />
));
Passo 5: Renderizando o Componente
Por fim, vamos juntar todos esses elementos em um único componente que receberá a nota e exibirá as estrelas correspondentes.
import React from 'react';
import { Text, View } from 'react-native';
import { FontAwesome } from '@expo/vector-icons';
interface IRateProps {
data?: number;
}
function RenderStars({ data = 0 }: IRateProps) {
const limitedRating = Math.min(data, 5);
const integerRating = Math.floor(limitedRating);
const decimalRating = limitedRating - integerRating;
const fullStars = integerRating;
const halfStar = decimalRating >= 0.1;
const emptyStars = 5 - fullStars - (halfStar ? 1 : 0);
const fullStarsElements = Array.from({ length: fullStars }, (_, index) => (
<FontAwesome key={index} name="star" size={14} color="#FCA311" />
));
const halfStarElement = halfStar ? (
<FontAwesome name="star-half-full" size={14} color="#FCA311" />
) : null;
const emptyStarsElements = Array.from({ length: emptyStars }, (_, index) => (
<FontAwesome key={index} name="star-o" size={14} color="#FCA311" />
));
return (
<View style={{ flexDirection: 'row', width: '100%', alignItems: 'center' }}>
<Text style={{ color: '#1b1b1b', marginRight: 5 }}>{data.toFixed(1)}</Text>
{fullStarsElements}
{halfStarElement}
{emptyStarsElements}
</View>
);
}
export { RenderStars };
Considerações Finais
Esse componente é uma forma didática e visual de apresentar notas com estrelas, ajustando automaticamente a quantidade de estrelas cheias, meias e vazias conforme a nota fornecida. A função Math.min()
garante que o valor máximo não seja ultrapassado, enquanto Math.floor()
e operações matemáticas simples separam as partes inteira e decimal da nota. Por fim, elementos JSX são usados para renderizar visualmente as estrelas.