Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

104
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda