【发布时间】:2022-01-26 18:15:31
【问题描述】:
我正在尝试创建一个自定义挂钩,最终将在 NPM 上打包并在我工作的公司的项目内部使用。基本思想是我们希望包暴露一个提供者,它在挂载时将向服务器发出请求,该请求返回一个权限字符串数组,然后通过上下文将这些权限字符串提供给子组件。我们还需要一个函数can,它可以在提供程序中调用,它将接受一个字符串参数并根据上下文提供的权限数组中是否存在该字符串返回一个布尔值。
我一直在关注this article,但任何时候我从提供程序内部调用can,上下文总是以未定义的形式返回。下面是一个非常简化的版本,没有功能,我一直在尝试弄清楚发生了什么:
useCan/src/index.js:
import React, { createContext, useContext, useEffect } from 'react';
type CanProviderProps = {children: React.ReactNode}
type Permissions = string[]
// Dummy data for fake API call
const mockPermissions: string[] = ["create", "click", "delete"]
const CanContext = createContext<Permissions | undefined>(undefined)
export const CanProvider = ({children}: CanProviderProps) => {
let permissions: Permissions | undefined
useEffect(() => {
permissions = mockPermissions
// This log displays the expected values
console.log("Mounted. Permissions: ", permissions)
}, [])
return <CanContext.Provider value={permissions}>{children}</CanContext.Provider>
}
export const can = (slug: string): boolean => {
const context = useContext(CanContext)
// This log always shows context as undefined
console.log(context)
// No functionality built to this yet. Just logging to see what's going on.
return true
}
然后是我正在测试的简单 React 应用程序:
useCan/example/src/App.tsx:
import React from 'react'
import { CanProvider, can } from 'use-can'
const App = () => {
return (
<CanProvider>
<div>
<h1>useCan Test</h1>
{/* Again, this log always shows undefined */}
{can("post")}
</div>
</CanProvider>
)
}
export default App
我哪里错了?这是我第一次真正使用 React 上下文,所以我不确定在哪里查明问题出在哪里。任何帮助,将不胜感激。谢谢。
【问题讨论】:
-
let permissions: Permissions | undefined;你把这个变量初始化为未定义,当 CanProvider 返回上下文提供者时它仍然未定义。useEffect只发生在渲染之后。useEffect的目标是什么? -
@NicholasTower 最终,当提供程序首次挂载时,对 API 的调用将在
useEffect中进行,所以我想在那里分配虚拟数据来模拟它。 -
听起来像
permissions应该是一个状态,而不是一个局部变量。一旦数据可用,您将需要设置状态才能重新渲染。 -
@NicholasTower 是的,现在意识到这可能是问题所在。试图让一个精简的版本开始运行,但我认为在这种情况下,试图过于简单地保持它是破坏它的原因。
标签: reactjs typescript npm react-hooks react-context