Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 从数据库获取数据时使用效果无限循环_Reactjs_Firebase_Google Cloud Firestore_React Hooks - Fatal编程技术网

Reactjs 从数据库获取数据时使用效果无限循环

Reactjs 从数据库获取数据时使用效果无限循环,reactjs,firebase,google-cloud-firestore,react-hooks,Reactjs,Firebase,Google Cloud Firestore,React Hooks,在我的项目中,用于发送请求以获取我的用户数据并显示它们。我写了上面的代码,但我意识到如果我将“人”传递给useEffect的依赖项(第二个参数),react会向我的firebase发送无限请求,但是如果我删除并保持第二个参数为空,useEffect会正常工作,这两者之间的区别是什么 下面是进入无限循环的代码: const [people, setPeople]=useState([]) useEffect(() => { const unsubscribe=database.co

在我的项目中,用于发送请求以获取我的用户数据并显示它们。我写了上面的代码,但我意识到如果我将“人”传递给useEffect的依赖项(第二个参数),react会向我的firebase发送无限请求,但是如果我删除并保持第二个参数为空,useEffect会正常工作,这两者之间的区别是什么

下面是进入无限循环的代码:

const [people, setPeople]=useState([])

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [people]) // if i change the second parameter with an empty list this problem solved.

return (
    <div>
        <h1>TinderCards</h1>
        <div className="tinderCards_cardContainer">
        {people.map(person =>
           <TinderCard
            className="swipe"
            key={person.name}
            preventSwipe={["up","down"]}
           >
            <div style={{backgroundImage: `url(${person.url})`}} className="card">
                <h3>{person.name}</h3>

            </div>
            </TinderCard> 
            )}
        </div>

    </div>
)
useEffect(() => {
  ... setPeople() ... // <- people changed
}, [people]);         // <- run every time people changes
const[people,setPeople]=useState([])
useffect(()=>{
const unsubscribe=database.collection(“人”).onSnapshot(快照=>
setPeople(snapshot.docs.map(doc=>doc.data())
)
return()=>{
退订
}
},[people])//如果我用空列表更改第二个参数,这个问题就解决了。
返回(
火柴
{people.map(person=>
{person.name}
)}
)
问题
useffect
每次指定给依赖项数组的任何一个值发生更改时都会运行。因为,在
db
呼叫之后,您正在更新您的
人员。对数组
people
的引用发生变化,从而触发
useffect

解决方案 您不需要将人员放入依赖关系数组中。 您的
useffect
功能不依赖于
people

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [])

问题是在useEffect中设置状态后,
people
值将被更改,这将触发另一个useEffect调用,从而产生无限循环

您可以将其修改为:-

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [])


本质上,每当依赖项数组(第二个参数)中的任何依赖项发生变化时,
useffect
钩子都会运行内部函数代码

由于
setPeople
会改变人,因此效果会在无限循环中运行:

const [people, setPeople]=useState([])

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [people]) // if i change the second parameter with an empty list this problem solved.

return (
    <div>
        <h1>TinderCards</h1>
        <div className="tinderCards_cardContainer">
        {people.map(person =>
           <TinderCard
            className="swipe"
            key={person.name}
            preventSwipe={["up","down"]}
           >
            <div style={{backgroundImage: `url(${person.url})`}} className="card">
                <h3>{person.name}</h3>

            </div>
            </TinderCard> 
            )}
        </div>

    </div>
)
useEffect(() => {
  ... setPeople() ... // <- people changed
}, [people]);         // <- run every time people changes
正如您正确指出的,只要去掉
people
依赖项,就会告诉效果在组件“挂载”时只运行一次

另外,您可能想知道,如果您获取相同的精确结果,为什么
会发生变化。这是因为比较很浅,每次创建数组时,它都是不同的对象:

const a=[1,2,3];
常数b=[1,2,3];

console.log(a==b);// 主要问题是,在每次set调用时创建的人员数组是不同的。对象完全不同。 我也有这个问题,因为我想显示的内容,一旦一些新的“人”被添加到数据库从管理面板,但事实证明,如果不刷新这件事不能解决,否则你可以做你自己的钩子与适当的比较


也许你可以通过比较人物数组的长度来尝试。我还没有尝试过,但我认为它会起作用。

只需在那里使用一个空的依赖项数组作为
[]
,这样它只会被触发一次。