gpt4 book ai didi

javascript - slim -通过常规 Prop 传递使用上下文API(setContext/getContext)

转载 作者:行者123 更新时间:2023-12-03 07:18:26 25 4
gpt4 key购买 nike

这是一个简单的示例:

<script>
import Button from './Button.svelte';

let text = 'Click me!';
let sayHello = () => alert('Hello!');
</script>

<Button {text} {sayHello}/>
<Button {text} {sayHello}/>
<Button {text} {sayHello}/>

如果我做对了,由于可以有很多 <Button {text} {sayHello}/>,最好省略以某种方式传递的 Prop

这是 上下文API :
<script>
import Button from './Button.svelte';
import { setContext } from 'svelte';
import { text, sayHello } from './data.js';

setContext(text, 'Click me!');
setContext(sayHello, () => alert('Hello!'));
</script>

<Button/>
<Button/>
<Button/>

./Button.svelte的某处有 getContext()的用法等

那么,是否能够省略类似 Prop 传递的能力是使用Svelte的 Context API 的唯一原因?

最佳答案

So, is the ability to omit similar props passing is the only reason to use Svelte's Context API?



不,在我看来,它甚至不是上下文的很好用法。

这里的问题是,您混淆了父组件及其按钮子组件之间的数据关系。

使用 Prop 时,按钮需要哪些数据以及数据来自何处是很明显的。另一方面,使用上下文,您一次只能看到关系的一侧。在父级中,您看不到如何使用数据(甚至根本不使用数据)。在 child 中也是一样,您看不到它的来源。

另外,弄错 Prop 或删除仍然需要的 Prop ,将导致即时可见的开发者警告(充分说明问题的确切位置)。对于上下文,您可能最终得到一个未定义的值,该值将产生怪异的运行时行为,但难以跟踪。

因此,当您在编码过程中脑子里有了很多新鲜的东西时,节省一点打字可能是个好主意,但这实际上增加了代码的复杂性,可能会给您带来麻烦,并给您带来麻烦。事后很头疼……如果您需要我的意见,那不是一个很好的权衡。

但是,在某些情况下, Prop 不是一种选择。也就是说,当数据使用者组件不是数据提供者组件的直接子代时。

例如,您的应用程序中可能会有某种用户 session 。它很可能会存储在组件树根(例如App)的根附近的组件中,但在组件中需要更深层次的嵌套。例如,在显示用户名的组件中。或页面中其他位置,根据用户是否通过身份验证显示一些部分。

您可以通过 Prop 穿过线路的每个组件,但这有点发疯。这会将所有中间组件与它们绝对不关心的数据联系起来。

因此,在这种情况下,上下文是完全有意义的。您将在 setContext组件中使用 App,并且可以仅从需要它的组件中访问它。

另一个示例是某种“复合”组件,其中您具有包装组件(例如表单)和可以在其中使用的多个组件(例如输入),这取决于容器中的某些设置。

<Form>
<Input />
</Form>

在这里, Form组件无法将props传递给 Input组件,因为 Input并不是直接在 Form组件中创建的。它是通过一个插槽馈送给它的,而 Form无法看到此插槽的内容。

不过, Input嵌套在结果组件树中的 Form下,因此您可以通过上下文在它们之间传递数据。

综上所述,上下文实际上是指您无法使用 Prop 的情况。要么是因为它不切实际并导致体系结构不佳,要么是因为它在技术上是不可能的(插槽)。

作为上下文的替代方法,您可以将数据存储在专用的JS模块中,提供者和使用者都可以访问该JS模块(例如 import { setData, getData } from './data-source.js'),但会使您的组件成为单例。此数据只能是全局的。另一方面,有了上下文,您可以根据需要拥有任意数量的隔离数据“范围”,每个数据提供程序组件实例一个。在上面的 Form示例中,多个 <Form>组件可以同时在您的应用程序中共存,每个组件在上下文中都有自己的数据。 (它们甚至可以嵌套在彼此内部,并且可以工作。)

总结一下,这是一条建议。 Svelte中的上下文是使用JS Map对象实现的,因此您不必使用原始字符串作为上下文键。我通常会使用从 constants.js模块之类的东西导出的普通对象(如果想要的话,也可以使用Symbol)。这在很大程度上缓解了我前面提到的模糊和IDE混淆问题。
constants.js
export const key = {name: 'my-context'}
Form.svelte
<script>
import { setContext } from 'svelte'
import { key } from './constants.js'

setContext(key, { ... })
</script>

<slot />
Input.svelte
<script>
import { getContext } from 'svelte'
import { key } from './constants.js'

const { ... } = getContext(key)
</script>

...

这消除了与原始字符串可能发生的上下文键冲突的任何风险。它将错误地快速转换为失败故障并发出严重的崩溃错误(这很好)。而且它为您的IDE提供了关于代码中发生的情况的更好的线索(开发人员可以轻松地解析ES导入,而字符串只是它们的随机Blob),从而在您使用代码时为您提供更多帮助我需要重构...

关于javascript - slim -通过常规 Prop 传递使用上下文API(setContext/getContext),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61387774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com