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

111
Views
Call React hook depending on Promise

I have an ID stored in AsyncStorage and depending on this call, I want to make a server request.

So something like this is needed:

AsyncStorage.getID().then(id => {
   useLoadFromServer(id)
}

But I always struggle with getting errors about using hooks wrong. So far I tried:

// First Approach
const MyScreen = () => {
  const [ID, setID] = useState()

  AsyncStorage.getID()
    .then(id => setID(id))
    .catch(e => console.log(e))
  
  const { data } = useLoadRoot(ID) // Not the ID from AsyncStorage is used
}
//Second Approach
const MyScreen = async () => {
  const [ID, setID] = useState()

  const IDPromise = AsyncStorage.getID()
  const { data } = useLoadRoot(await IDPromise) // Possible Unhandled Promise Rejection

also I tried to use useEffect, which leads to React Hooks must be called in a React function component or a custom React Hook function

The useLoadRoot-hook just calls another hook UseLoadFromEndpoint doing the axios.get()

When trying to move the AsyncStorage-Request to the customHook, I get the same errors, as I call the useLoadFromEndpoint-hook incorrectly, but I have to / want to reuse the UseLoadFromEndpoint-Hook. How can I achive this?

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

You need to either modify the useLoadRoot hook or wrap that logic in a child component. Hooks don't allow conditional usage.

Route 1: Rewrite useLoadRoot

const useLoadRoot = (id) => {
  const getRoot = async (rootId) => ...;
  const [root, setRoot] = useState();

  useEffect(() => {
    if (id != undefined) { 
       await getRoot(id);
    }
  }, [id]);

  return root;
}

This is just one way to achieve what you want. You can pass in an enabled property that is a boolean that allows requests only if true. This is the approach that is used in react-query, for example (see: docs).

Route 2: Conditional child component

const Parent = () => {
  const [ID, setID] = useState()
  
  useEffect(() => {
    AsyncStorage.getID()
      .then(id => setID(id))
      .catch(e => console.log(e))
  }, []);

  return ID ? <WithFetchRoot rootId={ID}/> : null; //could be a loader component instead of null
}

const WithFetchRoot = (id) => {
  const root = useLoadRoot(ID);

  ...
}
about 4 years ago · Juan Pablo Isaza Report

0

The rules of hooks state that all hooks must run in the same order with each render cycle. This means we need to write conditional logic in a particular way. I would recommend this.

const MyScreen = () => {
  const [ID, setID] = useState()
  cosnt [data, setData] = useState()

  useEffect(() => {
    const getData = async () => {
      const id = await AsyncStorage.getID()
      setID(id)
      const { data } = useLoadRoot(id)
      setData(data)
    }
    getData()
  })
  
  if (data) {
    // do stuff
  }
  return null
}
about 4 years ago · Juan Pablo Isaza Report

0

It's because you have no return. All react components should return something so return null from your component and it should solve your problem. Also, to avoid unnecessary rendering, you should do it in useEffect with an empty array so it only get triggers once (after the component mounts).

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!