【发布时间】:2021-12-31 11:19:10
【问题描述】:
我有一个 Auth 屏幕和一个 HomeScreen,为了管理我正在使用的 Context API 的状态,我有 2 个状态 -> 1) user 我决定是否通过身份验证的状态(同时从服务器获取信息),2)loading 状态以在所有这些发生时显示加载屏幕。问题是,一切正常,甚至将 user 的状态从 null 设置为来自我的 API 的明确定义的对象,并且以同样的方式我正在更改我的 loading 状态但它没有改变,它是false 每次尽管我使用相同的方法进行调度。
上下文文件:
import React, { createContext, useContext, useReducer } from 'react';
import {UserReducer} from './reducers';
const initialState = {
user: null,
loading: false,
};
const UserContext = createContext(initialState);
export const UserProvider = ({children}) => {
const [globalState, dispatch] = useReducer(UserReducer, initialState);
return (
<UserContext.Provider value={{
user: globalState.user,
loading: globalState.loading,
dispatch,
}} >
{children}
</UserContext.Provider>
);
};
export default function() {
return useContext(UserContext);
}
动作:
export const SET_USER_DETAILS = (userDetails) => {
return {
type: 'SET_USER_DETAILS',
payload: userDetails,
};
};
export const SET_LOADING = (loadingState) => {
return {
type: 'SET_LOADING',
payload: loadingState,
};
};
减速机:
export const UserReducer = (state, action) => {
switch (action.type) {
case 'SET_USER_DETAILS':
return {
...state,
user: action.payload,
};
case 'SET_LOADING':
return {
...state,
loading: action.payload,
};
default:
return state;
}
};
主导航文件:
const Navigation = () => {
const {user, dispatch, loading} = useAuth();
console.log(user); // after successful fetch from api, I'm getting the desired user data.
console.log(loading); // PROBLEM => always false.
useEffect(() => {
checkUserLoggedInStatus(dispatch);
}, [dispatch]);
return loading ? (
<LoadingScreen />
) : !user ? (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Register" component={RegisterScreen} />
<Stack.Screen name="Verify" component={OTPVerificationScreen} />
</Stack.Navigator>
) : (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Message" component={MessageScreen} />
</Stack.Navigator>
);
};
checkUserLoggedInStatus 函数:
export const checkUserLoggedInStatus = (dispatch) => {
dispatch(SET_LOADING(true)); // NOT WORKING/NOT CHANGING THE LOADING STATE
AsyncStorage.getItem('token')
.then((token) => {
if (token) {
fetch(`${API_URL}/user/`, {
method: 'GET',
headers: {
...
},
})
.then(response => response.json())
.then((data) => {
if (data.type === 'success') {
const details = data.data.user;
dispatch(SET_USER_DETAILS(details)); // THIS IS WORKING FINE.
}
})
.catch((error) => {
console.log(error.message);
});
}
})
.catch((error) => {
console.log(error.message);
});
dispatch(SET_LOADING(false)); // NOT WORKING/NOT CHANGING THE LOADING STATE
};
我无法理解我做错了什么,因为我正在使用 SET_USER_DETAILS 动作/减速器功能做同样的事情,但我不知道 loading 状态有什么问题。
摘要:无法根据来自UserContext 的loading 状态呈现LoadingScreen。
如果有人可以帮助我,我将不胜感激!
谢谢!
【问题讨论】:
-
你可以查看这个如何使用上下文实时示例stackblitz.com/edit/…
-
嘿,谢谢您的评论,我使用的是
Context API而不是redux,尽管样板和概念非常相似,但我知道 contextAPI 是如何工作的,因为我能够更改user状态而不是loading状态,即使两个函数都是使用相同的方法编写的。你有什么解决办法吗?
标签: reactjs react-native react-hooks react-context