我有一个react应用程序,它使用ContextAPI来管理身份验证,我正试图在Svelte中实现类似的东西。
在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>
2条答案
按热度按时间46qrfjad1#
从React Context迁移到Svelte
Svelte和React中的上下文可能看起来很相似,但实际上它们的使用方式不同。因为在核心上,Svelte的上下文要有限得多。但这没关系。事实上,它实际上会让你的代码更容易编写和理解。
在Svelte中,您可以使用更多工具来传递应用程序的数据(并保持同步),而不仅仅是上下文。每个工具都做了几乎一件事(使一切都可预测),并且它们做得很好。其中,您有:
作为一个最近从React转向Svelte的人,我想我可以帮助解释这些方法之间的一些差异,并帮助你避免一些我的概念错误。我还将介绍生命周期方法的一些差异,因为如果你曾经使用
useEffect
,你可能会感到非常困惑,因为Svelte没有等效的API。然而,在Svelte中将所有东西结合在一起会使一切变得简单。Context
Svelte中的上下文做了一件事:将数据从父组件传递给任何子组件(不一定是直接子组件)。与React不同,context不是reactive的。它在组件挂载时设置一次,然后不会再次更新。我们将在第二次中了解“reactive context”。
请注意,上下文涉及两件事,一个键和一个值。上下文被设置为一个特定的键,然后可以使用该键检索值。与React不同,你不需要导出函数来检索上下文。上下文的键和值都可以是任何东西。如果你可以将其保存到一个变量,你可以将其设置为上下文。你甚至可以使用一个对象作为键!
店铺
如果你的数据需要在应用中的多个位置保持同步,那么商店就是一个不错的选择。商店是被动的,这意味着它们可以在创建后进行更新。与React或Svelte中的上下文不同,商店不会简单地将数据传递给其子节点。应用的任何部分都可以创建商店,你的应用程序的任何部分都可以读取商店。你甚至可以在单独的JavaScript文件中创建Svelte组件之外的商店。
然后在组件内部,您可以订阅存储。
美元符号订阅了存储。现在,每当存储被更新时,组件将自动重新呈现。
使用带上下文的store
现在我们已经有了存储和上下文,我们可以创建“React上下文”(我刚刚创造了一个术语,但它很有效)。存储很好,因为它们是React性的,上下文很好地将数据传递给子组件。但是我们实际上可以通过上下文传递存储。这使得上下文是React性的,存储是有作用域的。
现在,每当商店在父级中更新时,子级也会更新。商店当然可以做得更多,但如果你想复制React上下文,这是你在Svelte中可以得到的最接近的。它也少了很多样板!
使用reactive context和useEffect
Svelte没有
useEffect
的等价物。相反,Svelte有React式语句。在文档/教程中有很多关于这些的内容,所以我会保持简短。Svelte足够聪明,能够弄清楚依赖关系,只在需要时运行每个响应式语句。如果你创建了一个依赖循环,编译器会对你大喊大叫。
这意味着你可以使用React式语句来更新存储(从而更新上下文)。在这里,
valueStore
将在输入的每次击键时更新。由于这个存储是通过上下文传递的,因此任何子节点都可以获得输入的当前值。prop
在大多数情况下,props在React和Svelte中的功能完全相同。有一些差异,因为Svelte props可以利用双向绑定(不是必要的,但可能)。这确实是一个不同的对话,教程非常擅长教授使用props的双向绑定。
Svelte认证
好了,在完成所有这些之后,让我们看看如何创建身份验证 Package 器组件。
onAuthStateChanged
监听身份验证状态的更改onAuthStateChanged
,以防止内存泄漏ie3xauqp2#
在Svelte中,上下文是在父组件中使用
setContext(key, value)
设置的,子组件可以使用getContext(key)
访问value
对象。有关详细信息,请参阅文档。在您的情况下,上下文将像这样使用:
在这里,
currentUser
、login
和signup
(不知道这是从哪里来的?)被设置为setContext()
的上下文。要使用这个上下文,你可能会有这样的内容:正如文档中所写的,context是not reactive的,所以
currentUser
首先被转换为一个store,这样它就可以在一个child中订阅。至于useEffect
,Svelte有生命周期函数,你可以使用它在不同的点运行代码,比如onMount
或onDestroy
。如果你是Svelte的新手,他们的tutorial非常全面,有很多例子可以参考。
希望这有帮助!