Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

99
Vistas
React Function Component doesn't update view onClick

I'm new to React. I have a rating component that I created. The problem I'm having is onClick I can see the rating is updating in the console, but on the page I don't see the change happening. My understanding is that React components need to be pure functions and it's better to prefer functional components over classes. When I try to use the useState hook my rating is added to the previous state and doesn't update correctly on the page.

My first question is what is the best/preferred way to update state within a component? If I'm using a functional component do I have to use a hook?

Please see my code below

export default function Rating(props) {
    let stars = [];
    // const [stars, setStars] = useState([]);
    let star = '☆';

    for (let i = 0; i < props.stars; i++) {
        stars.push(star);
    }

    function rate(index) {
        let filledStar = '★'
        let stars = [];
        // setStars([])


        for (let i = 0; i < props.stars; i++) {
            stars.push(star);
        }
        stars.forEach((star, i) => {
            while (index >= 0) {
                stars[index] = filledStar;
                index--;
            }

        })
        console.log('stars filled', stars)
        return stars

     }

    return (
        <>
        <div className="stars">
            {stars.map((star, i) => (
                <h2 
                    key={i}
                    onClick={() => rate(i)}>{star}
                </h2>
            ))}
        </div>

        </>

    )

}

If I click the fourth star this is returned as expected, but the UI doesn't update

If I click the fourth star this is returned as expected, but the UI doesn't update.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Here's a working version that fills in stars up to and including the star that was clicked on - using useState, and useEffect.

const { Fragment, useEffect, useState } = React;

function Rating(props) {

  // Set state as an empty array
  const [stars, setStars] = useState([]);

  // Called by useEffect his function
  // creates a new array of empty stars
  function initStars() {
    const stars = [];
    for (let i = 0; i < +props.stars; i++) {
      stars.push('☆');
    }
    setStars(stars);
  }

  // Called when the component
  // first mounts, and called only once
  useEffect(() => {
    initStars();
  }, []);

  function rate(e) {

    // Get the id from the star dataset
    const { id } = e.target.dataset;

    // Create a fresh array
    const stars = [];

    // Loop; if the current index is less or
    // equal to the id set it as a filled star
    // otherwise set it to an empty star
    for (let i = 0; i < +props.stars; i++) {
      stars.push(i <= +id ? '★' : '☆');
    }

    // Set the state with the new array
    setStars(stars);

  }

  return (
    <div>
      {stars.map((star, i) => (
        <span
          className="star"
          key={i}
          data-id={i}
          onClick={rate}
        >{star}
        </span>
      ))}
    </div>
  );

};

ReactDOM.render(
  <Rating stars="10" />,
  document.getElementById('react')
);
.star { font-size: 1.8em; }
.star:hover { cursor: pointer; }
<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>

about 4 years ago · Juan Pablo Isaza Denunciar

0

So, it seems that I need to use the useState hook. I'm sure there is another way to do this, but this worked for me.

 export default function Rating(props) {
        const [stars, setStars] = useState([]);
        let star = '☆';

        function initStars() {
            const stars = [];
            for (let i = 0; i < props.stars; i++) {
               stars.push(star);
            }
            setStars(stars);
        }

        // Called when the component
        // first mounts, and called only once
        useEffect(() => {
            initStars();
        }, []);

        function rate(index) {
            console.log('index', index);
            let filledStar = '★'
            let stars = [];

            console.log('setStars', stars);

            for (let i = 0; i < props.stars; i++) {
               stars.push(star);
            }
            stars.forEach((star, i) => {
                while (index >= 0) {
                   stars[index] = filledStar;
                   index--;
                }

            })
            console.log('stars filled', stars)
            // return stars
            setStars(stars)

         }

         // console.log('stars', stars);

        return (
        <>
            <div className="stars">
                {stars.map((star, i) => (
                    <h2 
                        key={i}
                        onClick={() => rate(i)}>
                        {star}
                    </h2>
                ))}
            </div>

        </>

    )

}
about 4 years ago · Juan Pablo Isaza Denunciar

0

As you suggested, you will need to use hooks in order to seek the functionality you're looking for (or use a class component). In your current implementation, you're not actually using React states, so React doesn't know that you want it to re-render your component. Also, the stars array you're using in rate() is different from the stars array in your component. You don't seem to be making use of the stars array created and returned by rate()

How exactly have you tried to use useState?

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda