Skip to content
Advertisement

Show rating stars in react not showing any stars

I am building website of Mangas where each Manga has star reviews. I am done with backend but since I am very new to react, I can not figure out how to display stars on webpage. I’m developing it in Django so: id=”{{ rating }}” is a loop where I display each manga with title, rating and so on. console.log(prop.id) returns each manga rating 2 times so mangas with ratings 2, 4, 5 are logged as 2, 4, 5, 2, 4, 5.

code

{% block script %}
<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
{% endblock %}
<script type="text/babel">
    function Apicall(props) {
        props.star.forEach(prop => {
            return Render_rating(prop.id)
        });
        
    
       function Render_rating(props) {
           if (parseInt(Math.round(props) == 0)) {
            return (
                <img src="static/mangas/nostar.png"/>
            )
           }
           else {
           for (var i = 0; i = parseInt(Math.round(props)); i++) {
           return Render_stars()
        }
       } 
       
       function Render_stars() {
           return (
           <img src="static/mangas/fullstar.png"/>
           )
       }
    }
}
       ReactDOM.render(<Apicall star={document.querySelectorAll(".stars")}  />, document.getElementById('app'))
     </script>
{% for manga, rating in mangas %}
<div id="manga">
<a href="{% url 'manga' manga.id %}">
<div class="stars" id="{{ rating }}"></div>
<div id="app"></div>
<h1>{{ manga.title }}</h1>
<img src="{{ manga.image.url }}">
<br/>{% for genre in manga.genre.all %}{{ genre }}<br/>{% endfor %}
{{ manga.Description }}
</a>
</div>
{% endfor %}

error: Nothing was returned from render

Advertisement

Answer

I’m making two assumptions. 1) that your data is an array of objects, and 2) that your rating will be “out of five stars”

Have two functions: one to map over the array of objects, and another to create the stars for each object.

const { useState } = React;

function Example({ data }) {

  // Passing in a rating object,
  // create a new array, and then loop
  // pushing stars into the array depending
  // on the rating, and then returning the array
  function getStars(rating) {
    const stars = [];
    for (let i = 0; i < 5; i++) {
      if (rating - 1 < i) {
        stars.push(<span>☆</span>);
      } else {
        stars.push(<span>★</span>);
      }
    }
    return stars;
  }

  // `map` over the data, and for each object
  // call `getStars`, and return an array of JSX
  // that contains the manga name, and the result of that call
  function getRatings(data) {
    return data.map(obj => {
      return (
        <div>
          <span className="name">{obj.name}</span>
          <span className="stars">{getStars(obj.rating)}</span>
        </div>
      );
    });
  }

  // Then just call `getRatings`
  return (
    <div>
      {getRatings(data)}
    </div>
  );

}

const data = [
  { name: 'Manga1', rating: 1 },
  { name: 'Manga2', rating: 4 },
  { name: 'Manga3', rating: 5 },
  { name: 'Manga4', rating: 0 },
  { name: 'Manga5', rating: 2 },
];

ReactDOM.render(
  <Example data={data} />,
  document.getElementById('react')
);
.name { margin-right: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

To (mostly) satisfy Cesare’s comment here’s the same code but as separate components.

const { useState } = React;

function Example({ data }) {

  function getRatings(data) {
    return data.map(obj => {
      return <Rating data={obj} />
    });
  }

  return (
    <div>
      {getRatings(data)}
    </div>
  );

}

function Rating({ data }) {
  return (
    <div>
      <span className="name">{data.name}</span>
      <Stars rating={data.rating} />
    </div>
  );
}

function Stars({ rating }) {
  
  function buildStars(rating) {
    const stars = [];
    for (let i = 0; i < 5; i++) {
      if (rating - 1 < i) {
        stars.push(<Star type="white" />)
      } else {
        stars.push(<Star type="black" />)
      }
    }
    return stars;
  }
  
  return (
    <span className="stars">
      {buildStars(rating)}
    </span>
  );

}

function Star({ type }) {
  if (type === 'white') return <span>☆</span>
  return <span>★</span>
}

const data = [
  { name: 'Manga1', rating: 1 },
  { name: 'Manga2', rating: 4 },
  { name: 'Manga3', rating: 5 },
  { name: 'Manga4', rating: 0 },
  { name: 'Manga5', rating: 2 },
];

ReactDOM.render(
  <Example data={data} />,
  document.getElementById('react')
);
.name { margin-right: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement