使用带React Hooks的Firebase

发布于:2021-02-19 00:00:20

0

121

0

React Firebase 应用程序 身份验证 hooks

本教程演示如何在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时获取配方。我们希望为我们的组件提供errorloadingrecipe状态。

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。它提供了一些有用的帮助,允许我们重用上面编写的一些逻辑。