useReducer:无法使用 userReducer 获取初始状态
useReducer: Not able to get the initial state using userReducer
我已经实现了 useReducer 以根据操作类型分派操作,并且每次我根据操作类型更新状态变量时,但在尝试读取初始状态时总是遇到错误。也许我的代码可以解释更多。
我在尝试读取 initialLoginState.isLoading 时遇到错误。
App.js代码:
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import BottomNavigation from './src/Navigations/BottomNavigation';
import AuthStackNavigation from './src/Navigations/AuthStackNavigation'
import { useState, useEffect, useMemo, useReducer } from 'react';
import { View } from 'react-native-animatable';
import { ActivityIndicator } from 'react-native';
import { AuthenticationContext } from './src/context/AuthenticationContext'
export default function App() {
//Initial state values
const initialLoginState = {
isLoading: false,
userName: null,
userToken: null
}
//Reducer function
const loginReducer = (action, prevState) => {
switch (action.type) {
case 'LOGIN':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false,
};
case 'REGISTER':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false,
};
case 'RETRIEVE_TOKEN ':
return {
...prevState,
userToken: action.token,
isLoading: false
};
}
}
//Defining useReducer
const [newLoginState, dispatch] = useReducer(loginReducer, initialLoginState);
const authContext = useMemo(() => ({
signIn: (email, password) => {
// setUserToken('abc');
// setIsLoading(false);
console.log("called")
let userToken
userToken = null;
if (email == 'user' && password == 'pass') {
userToken = 'abc';
}
dispatch({ type: 'RETRIEVE_TOKEN', id: email, token: userToken })
},
signOut: () => {
dispatch({ type: 'LOGOUT', })
},
signUp: () => {
setUserToken(null);
setIsLoading(false);
}
}), []);
useEffect(() => {
let userToken;
userToken = "dfsdfsdf"
dispatch({ type: 'REGISTER', token: userToken })
}, [])
if (initialLoginState.isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}>
<ActivityIndicator size='large'></ActivityIndicator>
</View>
)
}
return (
<AuthenticationContext.Provider value={authContext}>
<NavigationContainer>
{initialLoginState.userToken !== null ?
<BottomNavigation />
:
<AuthStackNavigation />
}
</NavigationContainer>
</AuthenticationContext.Provider>
);
}
错误:
TypeError: undefined is not an object (evaluating 'newLoginState.isLoading')
- node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
- node_modules/react-native/Libraries/LogBox/LogBox.js:59:8 in errorImpl
- node_modules/react-native/Libraries/LogBox/LogBox.js:33:4 in console.error
首先,reducer 函数的 switch 中的 default case 丢失了!
其次,你能把整个组件代码(只是需要的部分!)因为我没有问题 运行 你的代码甚至 没有默认大小写!
尝试将 reducer 函数更新为此(翻转参数!):
//Reducer function
//- const loginReducer = (action, prevState) => {
const loginReducer = (prevState, action) => {
switch (action.type) {
case 'LOGIN':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false,
};
case 'REGISTER':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false,
};
case 'RETRIEVE_TOKEN ':
return {
...prevState,
userToken: action.token,
isLoading: false
};
default:
return prevState;
}
}
不要忘记默认大小写!
我已经实现了 useReducer 以根据操作类型分派操作,并且每次我根据操作类型更新状态变量时,但在尝试读取初始状态时总是遇到错误。也许我的代码可以解释更多。
我在尝试读取 initialLoginState.isLoading 时遇到错误。
App.js代码:
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import BottomNavigation from './src/Navigations/BottomNavigation';
import AuthStackNavigation from './src/Navigations/AuthStackNavigation'
import { useState, useEffect, useMemo, useReducer } from 'react';
import { View } from 'react-native-animatable';
import { ActivityIndicator } from 'react-native';
import { AuthenticationContext } from './src/context/AuthenticationContext'
export default function App() {
//Initial state values
const initialLoginState = {
isLoading: false,
userName: null,
userToken: null
}
//Reducer function
const loginReducer = (action, prevState) => {
switch (action.type) {
case 'LOGIN':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false,
};
case 'REGISTER':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false,
};
case 'RETRIEVE_TOKEN ':
return {
...prevState,
userToken: action.token,
isLoading: false
};
}
}
//Defining useReducer
const [newLoginState, dispatch] = useReducer(loginReducer, initialLoginState);
const authContext = useMemo(() => ({
signIn: (email, password) => {
// setUserToken('abc');
// setIsLoading(false);
console.log("called")
let userToken
userToken = null;
if (email == 'user' && password == 'pass') {
userToken = 'abc';
}
dispatch({ type: 'RETRIEVE_TOKEN', id: email, token: userToken })
},
signOut: () => {
dispatch({ type: 'LOGOUT', })
},
signUp: () => {
setUserToken(null);
setIsLoading(false);
}
}), []);
useEffect(() => {
let userToken;
userToken = "dfsdfsdf"
dispatch({ type: 'REGISTER', token: userToken })
}, [])
if (initialLoginState.isLoading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignContent: 'center' }}>
<ActivityIndicator size='large'></ActivityIndicator>
</View>
)
}
return (
<AuthenticationContext.Provider value={authContext}>
<NavigationContainer>
{initialLoginState.userToken !== null ?
<BottomNavigation />
:
<AuthStackNavigation />
}
</NavigationContainer>
</AuthenticationContext.Provider>
);
}
错误:
TypeError: undefined is not an object (evaluating 'newLoginState.isLoading')
- node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
- node_modules/react-native/Libraries/LogBox/LogBox.js:59:8 in errorImpl
- node_modules/react-native/Libraries/LogBox/LogBox.js:33:4 in console.error
首先,reducer 函数的 switch 中的 default case 丢失了!
其次,你能把整个组件代码(只是需要的部分!)因为我没有问题 运行 你的代码甚至 没有默认大小写!
尝试将 reducer 函数更新为此(翻转参数!):
//Reducer function
//- const loginReducer = (action, prevState) => {
const loginReducer = (prevState, action) => {
switch (action.type) {
case 'LOGIN':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false
};
case 'LOGOUT':
return {
...prevState,
userName: null,
userToken: null,
isLoading: false,
};
case 'REGISTER':
return {
...prevState,
userToken: action.token,
userName: action.id,
isLoading: false,
};
case 'RETRIEVE_TOKEN ':
return {
...prevState,
userToken: action.token,
isLoading: false
};
default:
return prevState;
}
}
不要忘记默认大小写!