объединить состояния для рейтингового компонента - PullRequest
0 голосов
/ 14 июля 2020

Я пытаюсь сделать звездочку рейтинговой составляющей. Я использую тернарные операторы, чтобы проверить, является ли состояние истинным или нет. Если да, я использую желтую звезду или белую. Однако это похоже на плохую практику кода. Можно ли вместо того, чтобы повторять все эти тернарные операторы, каким-то образом объединить условия и отобразить только те желтые звезды, состояние которых истинно?

const [oneStar, setOneStar] = useState(false);
const [twoStar, setTwoStar] = useState(false);
const [threeStar, setThreeStar] = useState(false);
const [fourStar, setFourStar] = useState(false);
const [fiveStar, setFiveStar] = useState(false);

const ratings = [
    1,2,3,4,5
]

const setRating = (rating: number) => {
  console.log('rating', rating);
  if(rating == 1){
      setOneStar(true);
      setTwoStar(false);
      setThreeStar(false);
      setFourStar(false);
      setFiveStar(false);
  }
  if(rating == 2){
    setOneStar(true);
    setTwoStar(true);
    setThreeStar(false);
    setFourStar(false);
    setFiveStar(false);
}
if(rating == 3){
    setOneStar(true);
    setTwoStar(true);
    setThreeStar(true);
    setFourStar(false);
    setFiveStar(false);
}
if(rating == 4){
    setOneStar(true);
    setTwoStar(true);
    setThreeStar(true);
    setFourStar(true);
    setFiveStar(false);
}
if(rating == 5){
    setOneStar(true);
    setTwoStar(true);
    setThreeStar(true);
    setFourStar(true);
    setFiveStar(true);
}
};

return (
<View style={styles.ratingContainer}>
    <TouchableOpacity onPress={() => setRating(1)}>
        {oneStar ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
    <TouchableOpacity onPress={() => setRating(2)}>
        {twoStar ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
    <TouchableOpacity onPress={() => setRating(3)}>
        {threeStar ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
    <TouchableOpacity onPress={() => setRating(4)}>
        {fourStar ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
    <TouchableOpacity onPress={() => setRating(5)}>
        {fiveStar ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
</View>
);
};

Ответы [ 4 ]

1 голос
/ 14 июля 2020

Примерно так:

const [stars, setStars] = useState(1);

...        

{
  [1, 2, 3, 4, 5].map((x, i) => (
    <TouchableOpacity onPress={() => setStars(i)}>
      {stars <= i ? (
        <Icon name="star" color="#ebba34" size={moderateScale(13)} />
      ) : (
        <Icon name="star-o" size={moderateScale(13)} />
      )}
    </TouchableOpacity>
  ));
}
0 голосов
/ 14 июля 2020
const Rating = () => {
  const [currentRating, setRating] = useState(0);

  const styles = rating => {
    return {
      width: "20px",
      height: "20px",
      border: "1px solid",
      backgroundColor: stars >= rating ? "green" : "red"
    };
  };

  const rates = [1, 2, 3, 4, 5];

  const stars = rates.map(rate => {
    return currentRating >= rate ? (
      <TouchableOpacity onPress={() => setRating(rate)}>
        <Icon name="star" color="#ebba34" size={moderateScale(13)} />
      </TouchableOpacity>
    ) : (
      <TouchableOpacity onPress={() => setRating(rate)}>
        <Icon name="star-o" size={moderateScale(13)} />
      </TouchableOpacity>
    );
  });

  return <View>{stars}</View>;
0 голосов
/ 14 июля 2020

Один из способов go об этом - отслеживать только то, сколько звездочек было «выбрано», когда пользователи нажимают на конкретную c звездочку.

function Rating() {
  const [stars, setStars] = React.useState(0);
  const ratings = [1, 2, 3, 4, 5];

  return (
    <View style={styles.ratingContainer}>
      {/* Iterate through all `ratings` and render stars for each */}
      {ratings.map(rating => (
        <TouchableOpacity key={rating} onPress={() => setStars(rating)}>
          {/* If `stars` is not 0 and `rating` is less than or equal 
              to the number of `stars`, then show a selected star */}
          {stars !== 0 && rating <= stars ? (
            <Icon name="star" color="#ebba34" size={moderateScale(13)} />
          ) : (
            <Icon name="star-d" size={moderateScale(13)} />
          )}
        </TouchableOpacity>
      ))}
    </View>
  );
}

Вот пример:

0 голосов
/ 14 июля 2020

Вы можете использовать номер для этого

const [stars, setStars] = useState(0);

, а затем просто использовать этот метод setStars. Не нужно setRating и все это повторение

   <TouchableOpacity onPress={() => setStars(1)}>
        {stars <= 1 ? 
      <Icon name= "star" color='#ebba34' size={moderateScale(13)} /> : <Icon name= "star-o" size={moderateScale(13)} />}
    </TouchableOpacity>
...