简体   繁体   English

鉴于 SolidJS 的反应性,为什么要使用 Context 和 Provider?

[英]Why to use Context and Provider given SolidJS reactivity?

I have this SPA project which authenticates and authorizes its users via access tokens (JWT).我有这个 SPA 项目,它通过访问令牌 (JWT) 对其用户进行身份验证和授权。 These short-lived access tokens has their refresh tokens as well, so when they expire the app should refresh the access token and replay the failing request(s).这些短期访问令牌也有自己的刷新令牌,因此当它们过期时,应用程序应刷新访问令牌并重播失败的请求。 To achieve this I come up with a function ( authAwareFetch ) that wraps global fetch to;为了实现这一点,我提出了一个 function ( authAwareFetch ),它将全局fetch包装到; 1. add the authorization header if an access token present (ie user has logged in) and 2. check if request fails (due to expired token) refresh the access token and replay the request. 1. 如果存在访问令牌(即用户已登录),则添加授权 header 和 2. 检查请求是否失败(由于令牌过期)刷新访问令牌并重播请求。

To find out if an access token present authAwareFetch file imports the token store ( tokenStore ), which is a mere SolidJS store to hold access token, its lifetime (valid-until as EPOCH time) and refresh token, created by createStore of SolidJS.要查明访问令牌是否存在, authAwareFetch文件会导入令牌存储 ( tokenStore ),它只是一个 SolidJS 存储,用于保存访问令牌、其生命周期(有效期至 EPOCH 时间)和刷新令牌,由 SolidJS 的createStore创建。
To be able to log users in I have this auth service which exports other functions among login ;为了能够让用户登录,我有这个 auth服务,它在login中导出其他功能; refreshAccessToken , logout . refreshAccessTokenlogout The service file also imports tokenStore , and its functions reads from and writes to the store.服务文件还导入tokenStore ,它的函数读取和写入存储。

Given the code organization above (stores and services in their own files) and being able to react changes (on and off a component, thanks to SolidJS), my question is what is the use-case of Context and Provider?考虑到上面的代码组织(商店和服务在他们自己的文件中)并且能够对变化做出反应(在组件上和组件下,感谢 SolidJS),我的问题是上下文和提供者的用例是什么? If I am going to import a hook for each and every component (eg useAuth ) wouldn't it be the same thing to import the store (to read from it) and the service (to update the store)?如果我要为每个组件(例如useAuth )导入一个钩子,导入商店(从中读取)和服务(更新商店)不是一回事吗? Am I missing something?我错过了什么吗?
Thanks in advance.提前致谢。

Context allows you pass values down the component tree without going through parent child relationship.上下文允许您将值向下传递到组件树,而无需通过父子关系。

Say you want to use access token in a component located three levels deep inside the component hierarchy:假设你想在位于组件层次结构深处三层的组件中使用访问令牌:

const [authoStore, setAuthStore] = createStore({ /* Contents */ });

<ParentA>
  <ParentB>
    <Child />
  </ParentB>
</ParentA>

You can either pass the store from ParentA to ParentB to Child:您可以将商店从 ParentA 传递到 ParentB 再到 Child:

<ParentA store={authStore}>
  <ParentB store={authStore}>
    <Child store={authStore} />
  </ParentB>
</ParentA>

Or you can create a context and pass the store as its value so that Child component can access it directly through Context API.或者您可以创建一个上下文并将商店作为其值传递,以便子组件可以直接通过上下文 API 访问它。

const AuthContext = createContext(defaultValue);
<AuthContext.Provider value={authStore}>
  <ParentA>
    <ParentB>
      <Child />
    </ParentB>
  </ParentA>
</AuthContext>

And inside the Child component:在 Child 组件中:

const Child = () => {
   const authStore = useContext(AuthContext);
   // Snipped
}

Now, if we go back to the original question, using a signal or a store is irrelevant because as long as the inner components has access to the auth token, you can use store, signal, localstorage or even plain Javascript object. But Context API provides an easy way to share values between components, no matter how deep they lie on the component hierarchy.现在,如果我们 go 回到最初的问题,使用信号或存储是无关紧要的,因为只要内部组件可以访问 auth 令牌,您就可以使用存储、信号、本地存储甚至普通的 Javascript object。但是上下文 API提供了一种在组件之间共享值的简单方法,无论它们在组件层次结构中的位置有多深。

There are added benefits, for example, you can overwrite a value on different levels of the component tree by providing a different value.还有一些额外的好处,例如,您可以通过提供不同的值来覆盖组件树不同级别的值。

Here ChildA will receive the value red while ChildB will receive blue :这里ChildA将收到值redChildB将收到blue

<ThemeContext.Provider value='red'>
  <ChildA />
  <ThemeContext.Provider value='blue'>
    <ChildB />
  </ThemeContext.Provider>
</ThemeContext.Provider>

You can pass any kind of value through context, including signals and stores.您可以通过上下文传递任何类型的值,包括信号和存储。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 React 中使用 Provider 覆盖全局上下文 - How to override global context using Provider in React 使用 Provider 的 context.read 触发小部件重建<T> () 方法 - Triggering Widget Rebuilds with Provider's context.read<T>() Method 为什么大部分代码使用Provider包而不使用GetX/Riverpod/Bloc? - Why most of the codes use Provider package and don't use GetX/Riverpod/Bloc? 无法在 flutter 中使用提供程序来处理身份验证流程 - Not able to use provider in flutter for handling Authentication flow 提供程序中的 notifyListeners 不工作导致在提供程序内使用 class? - notifyListeners in provider not working cause use class inside provider? 嵌套对象反应性 vue js - nested object reactivity vue js Flutter:无法调用提供商<t> .of(context) 来自定义在另一个文件中的 function。 ProviderNotFoundException</t> - Flutter: Can't call Provider<T>.of(context) from a function that is defined into another file. ProviderNotFoundException 为什么模型无法使用提供程序访问另一个模型? - Why model cannot access another model using provider? 如何在 Flutter 应用程序的 initState 期间使用来自 Provider 的数据 - How to use data from Provider during initState in Flutter application 不能从 FloatingActionButton 内部使用 context.read() - Can't use context.read() from inside FloatingActionButton
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM