我无法让我的 Context 在 React/Gatsby 项目中工作。
很简单,我一定漏掉了一些东西。
我有一个父组件,它创建上下文并在上下文提供程序中呈现两个子组件。两个孩子消耗了上下文。
当我运行此代码时,用户值不会更改,并且似乎始终是默认值。我不明白我做错了什么。
父组件是:
// parent
import React, { useEffect, useState, createContext } from 'react'
import type { PageProps } from 'gatsby'
import Navbar from '../../components/Navbar2'
import Main from '../../components/Main2'
export type Nullable<T> = T | null
export interface User {
name: string
email: string
}
const loadingTime = 1.5 // s
const loadUser = (): Promise<User> => {
return new Promise<User>((resolve) => {
setTimeout(() => {
resolve({
name: "Jeff",
email: '[email protected]',
})
}, loadingTime*1000)
})
}
export interface UserState {
user: Nullable<User>
isLoading: boolean
isLoaded: boolean
}
export const UserContext = createContext<UserState>({
user: null,
isLoading: true,
isLoaded: false,
})
const Page: React.FC<PageProps> = () => {
const [user, setUser] = useState<Nullable<User>>(null)
const [isLoading, setIsLoading] = useState<boolean>(false)
const [isLoaded, setIsLoaded] = useState<boolean>(false)
useEffect(() => {
console.log('useEffect')
setIsLoading(true)
loadUser()
.then(user => {
console.log('then')
setUser(user)
setIsLoaded(true)
})
.catch(error => {
console.log('catch')
setUser(null)
setIsLoaded(false)
})
.finally(() => {
console.log('finally')
setIsLoading(false)
})
}, [])
return (
<UserContext.Provider value={{
user: user,
isLoading: isLoading,
isLoaded: isLoaded,
}}>
<Navbar />
<Main />
</UserContext.Provider>
)
}
export default Page
还有两个孩子
// Navbar2.tsx
import React, { useContext } from 'react'
import { UserContext, UserState } from '../pages/tests/user2'
interface Props {}
const Navbar: React.FC<Props> = () => {
const { user, isLoading, isLoaded } = useContext<UserState>(UserContext)
return (
<div style={{borderBottom: '1px solid gray'}}>
Email: {isLoaded ? user?.email : (isLoading ? "..." : "No user")}
</div>
)
}
export default Navbar
和
// Main2.tsx
import React, { useContext } from 'react'
import { UserContext, UserState } from '../pages/tests/user2'
const Main = () => {
const userContext = useContext<UserState>(UserContext)
console.log('Main', userContext)
return (
<div>
{userContext.isLoaded ? (
<h1>
Welcome {userContext.user?.name}
</h1>
) : (userContext.isLoading ? (
'...'
) : (
"No user loaded"
))}
</div>
)
}
export default Main
欢迎任何帮助:-)
上面的代码是有效的 React 代码。
它在这里按预期工作https://codesandbox.io/s/hungry-gianmarco-sry9v9?file=/src/Page.tsx我也可以在另一个React框架中尝试它并且它可以工作(https:/ /nextjs.org)。
这实际上是一个盖茨比问题。
看起来像这样:https://github.com/gatsbyjs/gatsby/issues/25616
我没有尝试修复它,因为使用不接受基本有效 React 代码的 React 框架似乎是不明智的。相反,我决定使用另一个框架进行调查。