Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

109
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!