简体   繁体   中英

How to use useEffect inside map function?

I have two tables in Firebase: Vouchers & ClaimedVouchers. I am trying to display the vouchers that do not appear in the ClaimedVouchers table. So, I have a query that gets all of the vouchers, then another that checks if they're claimed and if it's claimed or not the function should return either true or false:

This is isClaimedAPI.js

    export default () => {
      var result;
    
      async function isClaimed(voucher, user) {
        var db = Firebase.firestore();
        console.log("voucher");
        await db
    .collection("ClaimedVoucher")
    .where("voucherID", "==", voucher)
    .where("userID", "==", user)
    .get()
    .then(function (querySnapshot) {
      if (querySnapshot.empty === false) {
        result = true;
      } else {
        result = false;
      }
    })
    .catch(function (error) {
      console.log("Error getting documents: ", error);
    });
  console.log(result, "this is result");

  return result;
      //Call when component is rendered
      useEffect(() => {
        isClaimed().then((result) => setResult(result));
      }, []);
    
      return [isClaimed];

    
 

And then in my main function:

 var user = Firebase.auth().currentUser;
    var uid = user.uid;
    const [getVouchers, voucherList, errorMessage] = getVouchersAPI(ID); //List of vouchers to be checked
    const [isClaimed] = isClaimedAPI();
    
    
    return(
<ScrollView>
    {voucherList.map((item, index) => {
              var voucher = item;
              
              var isVoucherClaimed = isClaimed(voucher.voucherID, uid);
              console.log("this is result, ", isVoucherClaimed);
              if (
                isVoucherClaimed === false
              ) {
                  return <Text>{item.name}<Text>
                }
    })}
  </ScrollView>
 );

Now nothing happens and I receive the following warning: [Unhandled promise rejection: FirebaseError: Function Query.where() requires a valid third argument, but it was undefined.] but I think this is unrelated to the issue.

Your isClaimed is an async function, meaning that it returns a promise - or a delayed result. If you want to wait for the result when calling isClaimed , you'll need to use await :

await isClaimed(voucher.voucherID, uid);
console.log(result);

This most likely isn't possible in a render method though, which is why (as Asutosh commented) you'll have to store the result in the state, and then use the state in your render method.

So the setup you need is:

  • Start the loading of all your data in componentDidMount or with useEffect .
  • When the data is loaded, put it in the state with setState or a state hook.
  • Use the data in your render method.

For a few examples of this, see:

Just to highlight how you can use isClaimed as hoook and set state calling a async function inside it. Later use the above hook in a react component. Please follow below sanbox.

https://codesandbox.io/s/confident-cray-4g2md?file=/src/App.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM