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

314
Visualizações
React: Why is my variable only defined on the first render but undefined on subsequent renders?

React noob here.

I am having a hard time understanding how the useEffect and useState hooks work.

My App fetches data which upon retrieval needs to be rendered.

I am using the then() function to ensure that the variables are defined in the correct order. I have also tried using multiple useEffect() functions to guarantee the proper chronology. However, for whatever reason, my current variable is undefined. It is only defined on the first render.

import React, { useEffect, useState } from 'react'

export default function Answers() {

  const [questions, setQuestions] = useState([])
  const [current, setCurrent] = useState()

  useEffect(() => {
    fetch('http://localhost:8000/questions')
      .then(res => res.json())
      .then(data => setQuestions(data))
      .then(setCurrent(questions[0]))
  }, [])

  return (
    <div>
      <ul>
        {console.log(current['answers'])}
        {current['answers'].map(item => <li>{item}</li>)}
      </ul>
    </div>
  )
}

Here is the data being fetched:

{
  "questions": [
    {
      "id": 1,
      "question": "to work",
      "answers": ["yapmak", "gitmek", "çalışmak", "gelmek"],
      "correct": 3
    },
    {
      "id": 2,
      "question": "to know",
      "answers": ["gitmek", "bilmek", "çalışmak", "gelmek"],
      "correct": 2
    },
    {
      "id": 3,
      "question": "to want",
      "answers": ["istemek", "gitmek", "çalışmak", "konuşmak"],
      "correct": 1
    }
  ]
}
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

Code inside the useEffect hook is not doing what you probably expect.

First of all

.then(setCurrent(questions[0]))

will immediately call the function. You probably meant to write:

.then(() => setCurrent(questions[0]))

but that's still not correct because questions[0] will be undefined.

To understand why it will be undefined, you need to know two things about state update in React:

  • It is updated asynchronously
  • It is constant within a particular render of a component. Component can't see the updated state until it re-renders

In light of the above two points, we cannot use questions in the third then() method's callback function.

What you need to do is return the data from the 2nd then method's callback function as shown below:

fetch('http://localhost:8000/questions')
   .then(res => res.json())
   .then(data => { 
      setQuestions(data);
      return data; 
   })
   .then(data => setCurrent(data[0]))

Returning data from the callback of second then() method's callback function is needed to pass the data from the callback function of second then() to the callback function of third then() method.

Remove unnecessary "then()" method call

You don't really need the last then() method to call setCurrent - you can call it inside the second then() method.

fetch('http://localhost:8000/questions')
   .then(res => res.json())
   .then(data => { 
      setQuestions(data);
      setCurrent(data[0]);
   })

Using the useEffect hook

Alternative option is to update current state inside another useEffect hook that executes whenever questions state is updated.

(following useEffect hook will execute after questions state has been updated and the component has re-rendered as a result of that state update)

useEffect(() => {
  setCurrent(questions[0]);
}, [questions]);

If you take this approach, then the first useEffect could be re-written as:

useEffect(() => {
  fetch('http://localhost:8000/questions')
    .then(res => res.json())
    .then(data => setQuestions(data))
    .catch(error => { /* handle error */ });
}, []);

Note: Not related to your problem but you shouldn't omit the catch() method call to catch and handle any errors during the HTTP request.

about 4 years ago · Juan Pablo Isaza Relatório

0

The problem is in the way you set the current value, when you're calling setCurrent, the questions state is not ready yet. Try adding an additional useEffect hook that reacts to changes in questions:

useEffect(() => {
    fetch('http://localhost:8000/questions')
      .then(res => res.json())
      .then(data => setQuestions(data))
  }, []);

useEffect(() => {
    if (questions) {
        setCurrent(questions[0]);
    }
}, [questions]);
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