react钩子useeffect缺少依赖项:“getcontacts”

g6ll5ycj  于 2021-09-23  发布在  Java
关注(0)|答案(2)|浏览(325)

在发布以下内容之前,我已经查看了stackoverflow上的类似帖子,但没有一篇解决了我的问题。
我对从firestore数据库中响应和获取数据是新手。下面的代码根据需要工作,但在react中获得此提示

import React, {useState, useEffect} from 'react'
import {db} from '../firebase'

const ListRecord = () => {

    const [details, setDetails] = useState([]);

    useEffect(() => {
        getContacts()

    },[]);

        const getContacts = async() => {
            await db.collection('contacts').get().then((querySnapshot) => {
            let arr = []
            querySnapshot.forEach((doc) => {
                arr.push({id: doc.id, value: doc.data()})
            });
                setDetails(arr);  
            });
            console.log(details);
            return details
        }

    return (
        <div>
            <h2>List Contact Details</h2>
        </div>
    )
}

export default ListRecord

根据其他类似的帖子,我尝试将getcontacts函数移动到useffect体中,这会使提示符消失,但是getcontacts函数会在一个连续的循环中运行。

我不确定我错过了什么,任何帮助都将不胜感激。

kognpnkq

kognpnkq1#

有不同的潜在解决方案:

1.将getcontacts()移动到useeffect()挂钩内:

如果只调用一次getcontacts(),并且只在组件第一次装载时调用,那么这可能是最符合逻辑的解决方案。

useEffect(() => {
  const getContacts = async () => {
    await db.collection('contacts').get().then((querySnapshot) => {
      let arr = []
      querySnapshot.forEach((doc) => {
        arr.push({
          id: doc.id,
          value: doc.data()
        })
      });
      setDetails(arr);
    });
    //console.log(details);
    //return details // why are you returning details?
  }

  getContacts()
}, [setDetails]); // setDetails() is granted to never change therefore the hook will never re-run

当然,你也可以用一个生命:

useEffect(() => {
  (async function() {
    // ... same body as getContacts 
  })()
}, [setDetails])

2.使用usecallback()钩子:

这是你可能想做的事情,如果 getContacts() 多次调用(例如,当组件安装时,每次某些道具更改时,或者当您单击某些按钮时)

const getContacts = useCallback(async () => {
  await db.collection('contacts').get().then((querySnapshot) => {
    let arr = []
    querySnapshot.forEach((doc) => {
      arr.push({
        id: doc.id,
        value: doc.data()
      })
    });
    setDetails(arr);
  });
  //console.log(details);
  //return details // why are you returning details?
}, [setDetail]); // setDetails() is granted to never change therefore getContacts() will never be re-created

useEffect(() => {
  getContacts()
}, [getContacts]); // as getContacts() never changes, this will run only once

3.将getcontacts()移出组件并使其成为独立函数:

如果要将相同的逻辑重用到其他组件中,这是有意义的:

// getContacts.js file
// OR this code could be in the ListRecord.js file but**outside**the component,
// although, in this case, solutions (1) or (2) would make more sense
import { db } from 'path/to/firebase'

export async function getContacts() {
  await db.collection('contacts').get().then((querySnapshot) => {
    let arr = []
    querySnapshot.forEach((doc) => {
      arr.push({
        id: doc.id,
        value: doc.data()
      })
    });
    return arr; // this time you HAVE TO return arr
  });
}

// ListRecord.js file
import React, { useState, useEffect } from 'react';
import { getContacts } from 'path/to/getContacts.js';

const ListRecord = () => {
  const [details, setDetails] = useState([]);

  useEffect(async () => {
    const arr = await getContacts();
    if (arr && arr.length > 0) setDetails(arr);
  }, [setDetails]);

  //...
}
wwodge7n

wwodge7n2#

我建议你看看怎么做 useEffect 它的依赖项列表在官方文档中起作用。
简而言之,请执行以下操作:

useEffect(() => {
  getContacts()
}, [getContacts]);

这意味着 getContacts 变化 useEffect 将重新运行。

相关问题