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

110
Vistas
State not updating on click in React

I need to update the player state on click (setPlayerState) but it's not being doing on time. I mean, it updates later on, so I get the first state only after the second click when the state has changed again. Does anyone know how to solve this?

  const [player, setPlayerState] = useState({
    name,
    assertions: 0,
    score: 0,
    gravatarEmail,
  });

  function handleClick({ target }) {
    const id = target.getAttribute('data-testid').includes('correct');
    let points = 0;
    if (id) {
      const level = questions[index].difficulty;
      if (level === 'hard') points = THREE;
      else if (level === 'medium') points = TWO;
      else points = ONE;
      setPlayerState({
        ...player,
        assertions: player.assertions + 1,
        score: player.score + (TEN + (timer * points)),
      });
    }
  }
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Some points in your codes stand out

  • You reference index inside of your if(id) ... conditional but index is not set.
  • ONE, TWO, THREE, and TEN are not set.
  • Question scoring logic is tangled with state update logic

Here is a minimal complete example that fixes these things and shows a better way to write onClick. Run the code example and click the question buttons to see how assertions and score updates respectively.

function App({ questions = [] }) {
  const [player, setPlayer] = React.useState({
    name: "Hanna",
    assertions: 0,
    score: 0,
  })
  function calcScore(difficulty) {
    switch (difficulty) {
      case "hard": return 3
      case "medium": return 2
      default: return 1
    }
  }
  function onClick(question) { return event => {
    if (event.target.getAttribute("data-test-id").includes("correct"))
      setPlayer({
        ...player,
        assertions: player.assertions + 1,
        score: player.score + calcScore(question.difficulty)
      })
  }}
  return <div>
    {questions.map((q, key) =>
      <button key={key} data-test-id="correct" onClick={onClick(q)}>
        {q.ask}
      </button>
    )}
    <pre>{JSON.stringify(player, null, 2)}</pre>
  </div>
}
const questions = [
  { ask: "What is?", difficulty: "easy" },
  { ask: "How come?", difficulty: "medium" },
  { ask: "Seriously?", difficulty: "hard" }
]
ReactDOM.render(<App questions={questions} />, document.querySelector("#app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>

about 4 years ago · Juan Pablo Isaza Denunciar

0

Add a click state and useEffect to respond to it's change. It effectively forces two passes for the re-render.

Also try setPlayerState with previous value parameter i.e setPlayerState(player => which sometimes helps when updates are not noticed.

  const [player, setPlayerState] = useState({
    name,
    assertions: 0,
    score: 0,
    gravatarEmail,
  });

  const [clickTarget, setClickTarget] = useState(null)

  function handleClick({ target }) {
    setClickTarget(target )
  }

  useEffect(() => {
    if (!clickTarget) return

    const id = clickTarget.getAttribute('data-testid').includes('correct');
    let points = 0;
    if (id) {
      const level = questions[index].difficulty;

      points = (level === 'hard') ? THREE :
        (level === 'medium') ? TWO : ONE;

      setPlayerState(player => ({
        ...player,
        assertions: player.assertions + 1,
        score: player.score + (TEN + (timer * points)),
      }))
    }
    setClickTarget(null)
  }, [clickTarget])
about 4 years ago · Juan Pablo Isaza Denunciar

0

You can try to replace setState function called with the below code block to make sure state updated:

setPlayerState(s => ({
    ...s,
    assertions: s.assertions + 1,
    score: s.score + (TEN + (timer * points)),
}));
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