在 React 中与 Gatsby 一起使用上下文

问题描述 投票:0回答:1

我无法让我的 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

欢迎任何帮助:-)

reactjs gatsby react-context
1个回答
0
投票

上面的代码是有效的 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 框架似乎是不明智的。相反,我决定使用另一个框架进行调查。

© www.soinside.com 2019 - 2024. All rights reserved.