我已經使用firebase電子郵件/通過身份驗證和管理狀態創建了一個應用程式redux-toolkit,一切正常,除了一個糟糕的用戶體驗,也就是說,當應用程式打開時,需要一秒鐘來確定用戶是否登錄或不是,因此,我在 redux 中有一個加載狀態,這也可以正常作業,但是在初始加載期間,如果用戶之前登錄過,我可以先看到我的 LoginScreen 顯示,然后在一兩秒后顯示,它顯示我的 HomeScreen,所以我需要提供一個 LoadingScreen 以隱藏該轉換,并且僅在每次加載操作完成后才顯示特定螢屏。
我嘗試添加一個本地狀態并將其設定為 false 當一切都在onAuthStateChange函式內完成但它不起作用。
我的問題視頻:https ://drive.google.com/file/d/1a8Bu1bTqAANsWKDs0e5bjqVdZJWJRcMv/view?usp=sharing
請看一下錄音(上面的鏈接),以便您正確理解情況!
下面是我的代碼,入口檔案和redux工具包狀態檔案:
入口檔案:
const EntryPoint = () => {
const dispatch = useDispatch();
const user = useSelector(state => state.auth.user);
const authloading = useSelector(state => state.auth.loading);
useEffect(() => {
onAuthStateChanged(auth, result => {
if (result) {
const path = doc(db, 'users', result.uid);
getDoc(path)
.then(result => {
if (result.exists()) {
const data = result.data();
dispatch(
login({
displayName: data['displayName'],
email: data['email'],
photoURL: data['photoURL'],
phone: data['phone'],
}),
);
}
})
.catch(error => console.log('sign in error: ', error));
} else {
dispatch(logout());
}
dispatch(loading(false));
});
}, []);
if (authloading) return <Loader />;
return (
<Stack.Navigator>
{user ? <Stack.Screen name="Home" component={Home} /> : <Stack.Screen name="SignIn" component={SignIn} />}
</Stack.Navigator>
);
};
還原狀態:
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
user: null,
loading: true,
}
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
login: (state, action) => {
state.user = action.payload;
},
logout: (state) => {
state.user = null;
},
loading: (state, action) => {
state.loading = action.payload;
},
}
});
uj5u.com熱心網友回復:
我認為發生這種情況是因為您在設定loading = false之前進行了設定user,這很清楚,因為user將在getDoc呼叫后設定(這會產生 1 秒或 2 秒的“糟糕的 UX”)。
Reduxdispatch回傳一個 Promise,因此您可以在設定loading用戶后使用該 Promise 設定為 false:
const EntryPoint = () => {
const dispatch = useDispatch();
const user = useSelector(state => state.auth.user);
const authloading = useSelector(state => state.auth.loading);
useEffect(() => {
onAuthStateChanged(auth, result => {
if (result) {
const path = doc(db, 'users', result.uid);
getDoc(path)
.then(result => {
if (result.exists()) {
const data = result.data();
dispatch(
login({
displayName: data['displayName'],
email: data['email'],
photoURL: data['photoURL'],
phone: data['phone'],
}),
)
.then(result => { dispatch(loading(false)); }); //<-- after user is setted, remove loading
}
else dispatch(loading(false)); //<-- if result does not exixsts, remove loading
})
.catch(error => {
dispatch(loading(false)); //<-- in case of error, remove loading
console.log('sign in error: ', error);
});
} else {
dispatch(logout())
.then(result => { dispatch(loading(false)); }); //<-- after logout, remove loading
}
});
}, []);
if (authloading) return <Loader />;
return (
<Stack.Navigator>
{user ? <Stack.Screen name="Home" component={Home} /> : <Stack.Screen name="SignIn" component={SignIn} />}
</Stack.Navigator>
);
};
通過這種方式,您可以 100% 確定只有在設定用戶后才會將加載設定為 false(避免糟糕的用戶體驗)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/478686.html
上一篇:reactnativehooks只能在函陣列件的主體內部呼叫
下一篇:反應原生行內if陳述句
