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

115
Visualizações
UseEffect firing on initial render

I am creating a front end for an API that requires a user to input both an API key as well as a device name. The issue is that the UseEffect() fetch is firing with 'undefined' as the API key on render, so the API is throwing a 401 Error code and preventing the page from rendering so that the user can put in a key.

See below code:

Api.js

const Api = ({ device, key }) => {

    const [data, setData] = useState(null);
    

    useEffect(() => {
        fetch(`APILINK&key=${key}&id=${device}`)
        .then((res) => res.json())
        .then(setData)
    }, [device, key])

    if (data) return (
        <>
            <tbody>
                <tr>
                    <th>Date</th>
                    <th>Temp</th>
                    <th>C02</th>
                </tr>
                {data.samples.map((item) => (
                    <tr>
                        <td>{item.time}</td>
                        <td>{item.data[0]}</td>
                        <td>{item.data[1]}</td>
                    </tr>
                ))}
            
            </tbody>
        </>
    )
    return <div>No Data Found</div>
}

Home.js

const Home = ({ setDevice, setKey }) => {

    const getData = (e) => {
        e.preventDefault();
        const newDevice = e.target.deviceID.value;
        const apiKey = e.target.apiKey.value;
        setDevice(newDevice);
        setKey(apiKey);
    }

    return (
        <>
            <h1>Type in a device and provide an API key below:</h1>
            <form onSubmit={getData}>
                <input type='text' placeholder="Enter Device..." id='deviceID'></input>
                <input style={{display: 'block'}} type='text' placeholder="Enter API Key..." id='apiKey'></input>
                <button>Search</button>
            </form>
        </>

    )
}

export default Home;

App.js

const App = () => {

  const [device, setDevice] = useState()
  const [key, setKey] = useState()

  return (
    <>
      <Home setDevice={setDevice} setKey={setKey} />
      <Api device={device} key={key} />   
    </>
  )
}

export default App;

Any help is appreciated!!

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

You can wait until the key & device props are available:

useEffect(() => {
    key && device && fetch(`APILINK&key=${key}&id=${device}`)
        .then((res) => res.json())
        .then(setData)
}, [device, key])

useEffect is called right after the first render, regardless of the dependency array, so this protection above will not run the fetch call until those variables are available (when the dependency array "sees" there was a change and calls the useEffect callback).

You might want to show a loader if the key prop might take a while to be available.


I suggest to de-couple the logic which gets the data from the useEffect, because you might want to call getData directly, and it's also better for testing and general code order.

const getData = (key, device) => 
    key && device && fetch(`APILINK&key=${key}&id=${device}`)
        .then((res) => res.json())
        .then(setData);

useEffect(() => {
    getData(key, device)
}, [device, key])

Also, there's no need to fornull in useState(null), because useState() will behave identical.

about 4 years ago · Juan Pablo Isaza Relatório

0

You can put your fetch inside if statement

useEffect(() => {
        if(key && device){
          fetch(`APILINK&key=${key}&id=${device}`)
          .then((res) => res.json())
          .then(setData)
        }
    }, [device, key])
about 4 years ago · Juan Pablo Isaza Relatório

0

If your intention is to load data on render and not load more after that, I would make the following changes to your useEffect hook:

 useEffect(() => {
        if(!device || !key || data) return null
        fetch(`APILINK&key=${key}&id=${device}`)
        .then((res) => res.json())
        .then(setData)
    }, [data, device, key])
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