我有一个非常基本的自定义挂钩,它接受路径并从 firebase 返回文档
import React, { useState, useEffect, useContext } from 'react';
import { FirebaseContext } from '../sharedComponents/Firebase';
function useGetDocument(path) {
const firebase = useContext(FirebaseContext)
const [document, setDocument] = useState(null)
useEffect(() => {
const getDocument = async () => {
let snapshot = await firebase.db.doc(path).get()
let document = snapshot.data()
document.id = snapshot.id
setDocument(document)
}
getDocument()
}, []);
return document
}
export default useGetDocument
然后我使用 useEffect 作为 componentDidMount/构造函数来更新状态
useEffect(() => {
const init = async () => {
let docSnapshot = await useGetDocument("products/" + products[selectedProduct].id + "labels/list")
if(docSnapshot) {
let tempArray = []
for (const [key, value] of Object.entries(docSnapshot.list)) {
tempArray.push({id: key, color: value.color, description: value.description})
}
setLabels(tempArray)
} else {
setLabels([])
}
await props.finishLoading()
await setLoading(false)
}
init()
}, [])
但是,我从“throwInvalidHookError”中得到了不变违规,这意味着我违反了钩子规则,所以我的问题是你是否不能在 useEffect 中使用自定义钩子,或者我是否做了其他错误的事情。
据我所知,组件中的钩子应该始终保持相同的顺序。并且自从useEffect
有时会发生,并不是每个渲染都会破坏钩子规则 https://reactjs.org/docs/hooks-rules.html。在我看来就像你的useGetDocument
没有真正的需要。
我提出以下解决方案:
- 保持你的
useGetDocument
相同。
- 更改您的组件以具有
useEffect
具有document
作为依赖。
您的组件可能如下所示:
const Component = (props) => {
// Your document will either be null (according to your custom hook) or the document once it has fetched the data.
const document = useGetDocument("products/" + products[selectedProduct].id + "labels/list");
useEffect(() => {
if (document && document !== null) {
// Do your initialization things now that you have the document.
}
}, [ document ]);
return (...)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)