Javascript useContext正在react native中提供TypeError undefined状态属性
最近我开始学习React Context和hook,并相应地更新我现有的应用程序。但是面对一个我无法解决的问题。当我在我的组件中使用useContext时,它给了我一个错误Javascript useContext正在react native中提供TypeError undefined状态属性,javascript,reactjs,react-native,Javascript,Reactjs,React Native,最近我开始学习React Context和hook,并相应地更新我现有的应用程序。但是面对一个我无法解决的问题。当我在我的组件中使用useContext时,它给了我一个错误TypeError:无法读取未定义的属性“state”,我在网上搜索了一整天,并重新观看了几个教程系列,但不知道我遇到了什么问题以及如何解决它。所以,如果你们中的任何一个人能帮我解决这个问题,这对我真的很有帮助。这是我的密码: context.js import React, { createContext, useReduc
TypeError:无法读取未定义的属性“state”
,我在网上搜索了一整天,并重新观看了几个教程系列,但不知道我遇到了什么问题以及如何解决它。所以,如果你们中的任何一个人能帮我解决这个问题,这对我真的很有帮助。这是我的密码:
context.js
import React, { createContext, useReducer } from "react";
import AsyncStorage from '@react-native-community/async-storage';
export const AuthContext = createContext();
const initialState = {
isLoading: true,
newSession: false,
userToken: null
};
const createActions = dispatch => ({
signInPage: data => {
dispatch({ type: 'SIGN_IN_PAGE' });
},
signInAction: async data => {
const { student_id, password, database_name, site_url} = data;
if (student_id && password && database_name) {
// validating the login credential through api
}
},
signOut: async data => {
await AsyncStorage.removeItem('user_token');
dispatch({ type: 'SIGN_OUT' });
},
newSession: data => {
dispatch({ type: 'NEW_SESSION' });
},
loading: data => {
dispatch({ type: 'LOADING' });
}
});
const reducer = (state, action) => {
switch (action.type) {
case 'LOADING':
return {
...state,
isLoading: true,
newSession: false,
userToken: null
};
case 'SIGN_IN_PAGE':
return {
...state,
newSession: false,
isLoading: false,
userToken: null
};
case 'SIGN_IN_ACTION':
return {
...state,
isValidating: false,
newSession: false,
isLoading: false,
userToken: action.token,
};
case 'SIGN_OUT':
return {
...state,
newSession: true,
isLoading: false,
userToken: null,
};
case 'NEW_SESSION':
return {
...state,
newSession: true,
isLoading: false,
userToken: null
};
case 'RESTORE_TOKEN':
return {
...state,
newSession: false,
isLoading: false,
userToken: action.token
};
default:
return state;
}
};
const AuthProvider = (props) => {
const [state, dispatch] = useReducer(reducer, initialState);
const actions = createActions(dispatch);
return (
<AuthContext.Provider value={{ state, ...actions }}>
{props.children}
</AuthContext.Provider>
);
}
export default AuthProvider;
import React,{createContext,useReducer}来自“React”;
从“@react native community/async storage”导入异步存储;
export const AuthContext=createContext();
常量初始状态={
孤岛加载:是的,
新闻会话:错误,
userToken:null
};
const createActions=dispatch=>({
签名页面:数据=>{
分派({type:'SIGN_IN_PAGE'});
},
符号:异步数据=>{
const{student\u id、密码、数据库名称、站点url}=data;
if(学生id、密码和数据库名){
//通过api验证登录凭据
}
},
注销:异步数据=>{
等待AsyncStorage.removeItem('user_token');
分派({type:'SIGN_OUT'});
},
新闻会话:数据=>{
分派({type:'NEW_SESSION'});
},
加载:数据=>{
分派({type:'LOADING'});
}
});
const reducer=(状态、操作)=>{
开关(动作类型){
“装载”案例:
返回{
……国家,
孤岛加载:是的,
新闻会话:错误,
userToken:null
};
案例“在页面中签名”:
返回{
……国家,
新闻会话:错误,
孤岛加载:false,
userToken:null
};
案例“签署行动”:
返回{
……国家,
是:错,
新闻会话:错误,
孤岛加载:false,
userToken:action.token,
};
“注销”案例:
返回{
……国家,
新闻会话:是的,
孤岛加载:false,
userToken:null,
};
“新课程”案例:
返回{
……国家,
新闻会话:是的,
孤岛加载:false,
userToken:null
};
案例“还原令牌”:
返回{
……国家,
新闻会话:错误,
孤岛加载:false,
userToken:action.token
};
违约:
返回状态;
}
};
const AuthProvider=(道具)=>{
const[state,dispatch]=useReducer(reducer,initialState);
const actions=createActions(调度);
返回(
{props.children}
);
}
导出默认AuthProvider;
App.js
//packages
import React, { useContext } from 'react';
// third party packages
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import AsyncStorage from '@react-native-community/async-storage';
import { openDatabase } from 'react-native-sqlite-storage';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem
} from '@react-navigation/drawer';
// <----- assets and components ----->
import AuthProvider, { AuthContext } from './screens/context';
import BottomTabCotainer from './screens/tab/BottomTabContainer.js';
// drawer components
import { EditProfileScreen } from './screens/drawer/EditProfileScreen.js';
import { ChangePasswordScreen } from './screens/drawer/ChangePasswordScreen.js';
// stack components
import { OnlineClassroomScreen } from './screens/OnlineClassroomScreen.js';
import { InstituteCodeScreen } from './screens/InstituteCodeScreen.js';
import { LoginScreen } from './screens/LoginScreen.js';
import { NewSessionScreen } from './screens/NewSessionScreen.js';
import LoadingScreen from './screens/LoadingScreen.js';
// <!----- assets and components ----->
var db = openDatabase({ name: 'UserDatabase.db' });
const Drawer = createDrawerNavigator();
const Stack = createStackNavigator();
function CustomDrawerContent(props) {
const { signOut } = useContext(AuthContext);
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" onPress={signOut} />
</DrawerContentScrollView>
);
}
export default function App() {
const { state } = useContext(AuthContext);
React.useEffect(() => {
// Fetch the token from storage then navigate to our appropriate place
const bootstrapAsync = async () => {
let userToken;
try {
userToken = await AsyncStorage.getItem('user_token');
if (userToken) {
await AsyncStorage.getItem('expire_at', async (err, value) => {
if (value !== null && new Date(value) < (new Date())) {
newSession();
} else {
dispatch({ type: 'RESTORE_TOKEN', token: userToken });
}
});
} else {
new Promise((resolve, reject) => {
// creating users table
db.transaction(function (txn) {
txn.executeSql(
"SELECT name FROM sqlite_master WHERE type='table' AND name='users'",
[],
function (tx, res) {
if (res.rows.length == 0) {
txn.executeSql(
'DROP TABLE IF EXISTS users',
[],
function(tx, res) {
console.log('table dropped');
}
);
txn.executeSql(
'CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY AUTOINCREMENT, full_name VARCHAR(100), username VARCHAR(100), password VARCHAR(100), site_url VARCHAR(100), database_name VARCHAR(50), image_location VARCHAR(100) NULL)',
[],
function(tx, res) {
console.log('table created');
resolve(res);
}
);
} else {
resolve(res);
}
}
);
});
});
db.transaction(function (txn) {
txn.executeSql(
"SELECT * from users",
[],
function(tx, res) {
if (res.rows.length > 0) {
newSession();
} else {
signInPage();
}
}
);
});
}
} catch (e) {
// Restoring token failed
}
};
bootstrapAsync();
}, []);
return (
<AuthProvider>
<NavigationContainer>
{state.isLoading ? (
<Stack.Navigator>
<Stack.Screen name="Loading" component={LoadingScreen} options={{ headerShown: false }} />
</Stack.Navigator>
) : state.newSession ? (
<Stack.Navigator>
<Stack.Screen name="NewSession" component={NewSessionScreen} options={{ headerShown: false }} />
<Stack.Screen name="InstituteCode" component={InstituteCodeScreen} options={{ headerShown: false }} />
<Stack.Screen name="Login" component={LoginScreen} options={{ headerShown: false }} />
</Stack.Navigator>
) : state.userToken == null ? (
<Stack.Navigator>
<Stack.Screen name="InstituteCode" component={InstituteCodeScreen} options={{ headerShown: false }} />
<Stack.Screen name="Login" component={LoginScreen} options={{ headerShown: false }} />
</Stack.Navigator>
) : (
<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Dashboard" component={BottomTabCotainer} />
<Drawer.Screen name="Edit Profile" component={EditProfileScreen} />
<Drawer.Screen name="Change Password" component={ChangePasswordScreen} />
<Drawer.Screen name="OnlineClass" component={OnlineClassroomScreen} options={{ headerShown: false }} />
</Drawer.Navigator>
)}
</NavigationContainer>
</AuthProvider>
);
}
//包
从“React”导入React,{useContext};
//第三方软件包
从'@react-navigation/native'导入{NavigationContainer};
从'@react navigation/stack'导入{createStackNavigator};
从“@react native community/async storage”导入异步存储;
从'react native sqlite storage'导入{openDatabase};
进口{
createDrawerNavigator,
DroperContentScrollView,
付款人,
抽屉式
}来自“@react导航/抽屉”;
//
从“/screens/context”导入AuthProvider,{AuthContext};
从'/screens/tab/BottomTabContainer.js'导入BottomTabCotainer;
//抽屉组件
从“./screens/drawer/EditProfileScreen.js”导入{EditProfileScreen};
从'/screens/drawer/ChangePasswordScreen.js'导入{ChangePasswordScreen};
//堆栈组件
从'/screens/OnlineClassroomScreen.js'导入{OnlineClassroomScreen};
从'/screens/InstituteCodeScreen.js'导入{InstituteCodeScreen};
从'/screens/LoginScreen.js'导入{LoginScreen};
从'/screens/NewSessionScreen.js'导入{NewSessionScreen};
从“/screens/LoadingScreen.js”导入LoadingScreen;
//
var db=openDatabase({name:'UserDatabase.db'});
const Drawer=createDrawerNavigator();
const Stack=createStackNavigator();
功能CustomDrawerContent(道具){
const{signOut}=useContext(AuthContext);
返回(
);
}
导出默认函数App(){
const{state}=useContext(AuthContext);
React.useffect(()=>{
//从存储器中取出令牌,然后导航到适当的位置
const bootstrapAsync=async()=>{
让userToken;
试一试{
userToken=await AsyncStorage.getItem('user_token');
if(userToken){
等待AsyncStorage.getItem('expire_at',async(err,value)=>{
如果(值!==null&&new Date(值)<(new Date()){
新闻会话();
}否则{
分派({type:'RESTORE_TOKEN',TOKEN:userToken});
}
});
}否则{
新承诺((解决、拒绝)=>{
//创建用户表
数据库事务(功能(txn){
txn.executeSql(
“从sqlite_master中选择名称,其中type='table'和name='users'”,
[],
功能(发送、恢复){
if(res.rows.length==0){
txn.executeSql(
'如果存在用户,则删除表',
[],
功能(发送、恢复){
<AuthProvider>
<App/>
<AuthProvider/>