在Authenticate.js中,我有以下代码:
import React, { useContext, useState, useEffect } from "react"
import { auth } from "../firebase"
const AuthCt = React.createContext()
export function Auth() {
return useContext(AuthCt)
}
export function AuthComp({ children }) {
const [currentUser, setCurrentUser] = useState()
const [loading, setLoading] = useState(true)
function login(email, password) {
return auth.signInWithEmailAndPassword(email, password)
}
function logout() {
return auth.signOut()
}
useEffect(() => {
const unmount = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unmount
}, [])
const value = {
currentUser,
login,
signup
}
return (
<AuthCt.Provider value={value}>
{!loading && children}
</AuthCt.Provider>
)
}
这个上下文在其他Login.js
组件中像这样使用:
import { Auth } from "./Authenticate"
const Login = () => {
const { currentUser, login } = Auth()
而在 App.js
中我有:
import { AuthComp } from "./Authenticate";
function App() {
return (
<AuthComp>
<div> All others go here </div>
</AuthComp>
);
}
我该如何在Svelte中实现这个,特别是Authenticate
上下文?
由于不知道如何继续,我在Svelte中还没有做太多事情。到目前为止,我有一个AuthComp.svelte
文件。我不确定我是否做对了。
<script>
import { getContext, setContext } from 'svelte';
import { auth } from '../firebase';
import { writable } from 'svelte/store';
let Auth = getContext('AuthCt')
setContext('Auth', Auth)
let currentUser;
let loading = true;
const unmount = auth.onAuthStateChanged(user => {
currentUser = user;
loading = false
});
function login(email, password) {
return auth.signInWithEmailandPassWord(email,password)
}
function logout() {
return auth.signOut()
}
const value = { currentUser, login, signUp }
</script>
<slot value={value}></slot>
onMount
之外调用它将更早地运行它,因为onMount
等待组件出现在屏幕上。在服务器端渲染中,我一直在检查typeof window!== 'undefined'
(因为onAuthStateChanged
需要在浏览器中运行),而不是大多数情况下等待onMount
。不确定这是否是最好的方法,但对我而言已经起作用了。 - Nick