【问题标题】:React Context returning undefined with useContext使用useContext返回未定义的反应上下文
【发布时间】:2021-08-30 09:30:18
【问题描述】:

我在我的应用程序中设置了上下文。不在根目录,由于某种原因它返回 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

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

【问题讨论】:

    标签: javascript react-native react-context use-context


    【解决方案1】:

    您正在调用与StepProvider 相同级别的useStep

    您不能在包装它的同一组件中使用上下文中的值。

    您需要将StepProvider 包裹在父组件中然后使用它:

    import { StepProvider} from './StepContext'
    
    const ParenComponent = () => {
     <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 { 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 (
          <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 default OnboardingScreen
    
    

    【讨论】:

      【解决方案2】:

      您必须在使用提供程序包装的组件中使用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>
      )
      

      【讨论】:

        猜你喜欢
        • 2021-07-19
        • 2019-12-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-24
        • 2023-04-06
        相关资源
        最近更新 更多