发布于:2021-02-19 00:00:20
0
125
0
本教程演示如何在react应用程序中使用hooks来更好地集成firebase身份验证和firestore数据获取。在开始之前,对hooks、firebase身份验证和firestore有一个基本的了解是很有帮助的。最后,我们将构建示例应用程序中的一些hooks,Julienne.app。
监视身份验证
使用hooks和context的组合可以方便地访问React应用程序中任何位置的用户会话。我们可以将用户会话存储在context中,并将该context传递给子组件。然后,这些组件可以使用hooks访问会话对象。
首先,创造我们的环境。
const userContext = React.createContext({
user: null,
})
我们为context提供一个包含空会话对象的默认值。当我们使用firebase监视会话的更改时,这将发生变化。
接下来,我们将创建一个hooks,允许我们访问context。
export const useSession = () => {
const { user } = useContext(userContext)
return user
}
最后,让我们创建一个hooks来监视firebase身份验证状态。这个hooks将创建一个状态,它使用一个useState
回调来确定用户会话是否已经存在。回调是一种只在第一次装入组件时使用值初始化状态的有用方法。
接下来,我们使用监视身份验证更改的effect
。当您使用多种firebase登录方法之一触发登录(或注销)时,将使用当前身份验证状态调用onChange
函数。
最后,我们返回身份验证状态。
export const useAuth = () => {
const [state, setState] = React.useState(() => { const user = firebase.auth().currentUser return { initializing: !user, user, } })
function onChange(user) {
setState({ initializing: false, user })
}
React.useEffect(() => {
// listen for auth state changes
const unsubscribe = firebase.auth().onAuthStateChanged(onChange)
// unsubscribe to the listener when unmounting
return () => unsubscribe()
}, [])
return state
}
然后,我们可以在应用程序的顶层使用这个hooks,并使用context提供程序将用户会话提供给子组件。
function App() {
const { initializing, user } = useAuth()
if (initializing) {
returnLoading}
return ()
}
最后,在子组件中,我们可以使用hooks访问用户会话。
function UserProfile() {
const { user } = useSession() returnHello, {user.displayName}}
要真正登录或注销,根本不需要使用hooks。只需调用firebase.auth().signOut()
或事件处理程序中的各种登录方法。
获取文档
hooks对于使用firestore监视单个文档查询非常有用。在本例中,我们希望在提供id
时获取配方。我们希望为我们的组件提供error
、loading
和recipe
状态。
function useRecipe(id) {
// initialize our default state
const [error, setError] = React.useState(false) const [loading, setLoading] = React.useState(true) const [recipe, setRecipe] = React.useState(null)
// when the id attribute changes (including mount)
// subscribe to the recipe document and update
// our state when it changes.
useEffect(
() => {
const unsubscribe = firebase.firestore().collection('recipes') .doc(id).onSnapshot( doc => { setLoading(false) setRecipe(doc) }, err => { setError(err) } )
// returning the unsubscribe function will ensure that
// we unsubscribe from document changes when our id
// changes to a different value.
return () => unsubscribe()
},
[id]
)
return {
error,
loading,
recipe,
}
}
获取集合
获取一个集合非常相似,但是我们订阅了一个文档集合。
function useIngredients(id) {
const [error, setError] = React.useState(false)
const [loading, setLoading] = React.useState(true)
const [ingredients, setIngredients] = React.useState([])
useEffect(
() => {
const unsubscribe = firebase
.firestore()
.collection('recipes')
.doc(id)
.collection('ingredients') .onSnapshot( snapshot => { const ingredients = [] snapshot.forEach(doc => { ingredients.push(doc) }) setLoading(false) setIngredients(ingredients) }, err => { setError(err) } )
return () => unsubscribe()
},
[id]
)
return {
error,
loading,
ingredients,
}
}
如果您计划在整个应用程序中使用firebasehooks,我建议您检查react firebasehooks。它提供了一些有用的帮助,允许我们重用上面编写的一些逻辑。
作者介绍