使用useContext返回未定义的React上下文

plupiseo  于 2022-12-04  发布在  React
关注(0)|答案(3)|浏览(139)

我在我的应用程序中设置了上下文,而不是在根目录下,由于某种原因,它返回undefined。
我将此作为创建上下文的索引:

import React, { createContext, useContext, useReducer } from 'react'

type Action = { type: 'next' } | { type: 'back' }
type Dispatch = (action: Action) => void
type State = { step: number }
type StepProviderProps = { children: React.ReactNode }

const StepContext = createContext<{ state: State; dispatch: Dispatch } | undefined>(undefined)
const stepReducer = (state: State, action: Action) => {
  switch (action.type) {
    case 'next': {
      return { step: state.step + 1 }
    }
    case 'back': {
      return { step: state.step - 1 }
    }
    default: {
      throw new Error(`Unhandled action type`)
    }
  }
}

const StepProvider = ({ children }: StepProviderProps) => {
  const [state, dispatch] = useReducer(stepReducer, { step: 0 })
  const value = { state, dispatch }
  return <StepContext.Provider value={value}>{children}</StepContext.Provider>
}

const useStep = () => {
  const context = useContext(StepContext)
  if (context === undefined) {
    throw new Error('useStep should be used within StepProvider')
  } else {
    return context
  }
}

export { StepProvider, useStep }

然后将其导入到此处:

import { BodyText, H3, H5, H4 } from '../../typography'
import * as React from 'react'
import { Box, Icon } from '../../components'
import { useState } from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'
import { useNavigation } from '@react-navigation/native'
import { useAuthContext } from '../../context/AuthProvider'
import { Enum_Userspermissionsuser_Userrole } from '../../generated/graphql'
import Start from './Start'
import stepOne from './StepOne'
import { StepProvider, useStep } from './StepContext'

const OnboardingScreen = () => {
  const [stepper, setStepper] = useState([0, 1, 2, 3, 4, 5])

  const { navigate } = useNavigation()
  const { user } = useAuthContext()
  const {state:{step}} = useStep()
 

  return (
    <StepProvider>
      <Container px={5} justifyContent="flex-start" downbg hasNavbar={false}>
        <View style={{ flexDirection: 'row', justifyContent: 'space-evenly', marginTop:'12%'}}>
          {stepper.map((step, i) => (
            <Box height={5} width={50} bg="b2gpeach" borderRadius={11} key={i} />
          ))}
        </View>
        <Start />
        {console.log(step)}
        
      </Container>
      </StepProvider>
  )
}


export default OnboardingScreen

我想我应该能够获得上下文的控制台日志,但我得到了上下文未定义错误,我设置为检查上下文是否已定义。

r8uurelv

r8uurelv1#

您在与StepProvider相同的层级上呼叫useStep
不能在 Package 该值的同一组件中使用上下文中的值。
您需要在父组件中 Package StepProvider,然后使用它:
第一个

ig9co6j1

ig9co6j12#

必须在使用提供程序 Package 的组件中使用useContext

<StepProvider>
  <OnboardingScreen />
</StepProvider>

你可以这样做:

import { BodyText, H3, H5, H4 } from '../../typography'
import * as React from 'react'
import { Box, Icon } from '../../components'
import { useState } from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'
import { useNavigation } from '@react-navigation/native'
import { useAuthContext } from '../../context/AuthProvider'
import { Enum_Userspermissionsuser_Userrole } from '../../generated/graphql'
import Start from './Start'
import stepOne from './StepOne'
import { StepProvider, useStep } from './StepContext'

const OnboardingScreen = () => {
  const [stepper, setStepper] = useState([0, 1, 2, 3, 4, 5])

  const { navigate } = useNavigation()
  const { user } = useAuthContext()
  const {state:{step}} = useStep()
 
  // Provider removed
  return (
    <Container px={5} justifyContent="flex-start" downbg hasNavbar={false}>
      <View style={{ flexDirection: 'row', justifyContent: 'space-evenly', marginTop:'12%'}}>
      {stepper.map((step, i) => (
        <Box height={5} width={50} bg="b2gpeach" borderRadius={11} key={i} />
      ))}
      </View>
      <Start />
      {console.log(step)}
    </Container>
  )
}

// Export wrapped with provider
export default () => (
  <StepProvider>
    <OnboardingScreen />
  </StepProvider>
)
lnlaulya

lnlaulya3#

对我有效的方法是声明类型。2使用下面的逻辑:
我的身份验证上下文.tsx

...
1. interface contextValueTypes {
    login: Function,
    logout: Function,
    isLoading: boolean,
    userToken: string,
}

2. export const AuthContext = createContext<contextValueTypes>({
    login: Function,
    logout: Function,
    isLoading: false,
    userToken: "",
});
...

在我的App.js中

const App = () => {
  const { isLoading, userToken } = useContext(AuthContext);
  return (
    <AuthProvider>
        {userToken == null ? <AppStack /> : <AuthStack />}
    </AuthProvider>
  );
}

我希望这对你有帮助

相关问题