我正在使用React Native(0.61.2)和TypeScript(3.6.4)做一个移动应用程序。我正在使用React Native Firebase集合中的Firebase身份验证和Firebase Firestore。
我正在尝试:
我要在上下文中保存先前侦听器的userAuth,用户文档和品牌文档。
/**
* Types
*/
type UserAuth = FirebaseAuthTypes.User | null;
type User = UserDoc | null;
type Brand = BrandDoc | null;
type ContextProps = {
userAuth: UserAuth;
user: User;
brand: Brand;
} | null;
/**
* Context
*/
export const Context = createContext<ContextProps>(null);
function App() {
const [initializing, setInitializing] = useState(true);
const [listenUserAuth, setListenUserAuth] = useState(false);
const [userAuth, setUserAuth] = useState<UserAuth>(null);
const [listenUser, setListenUser] = useState(false);
const [user, setUser] = useState<User>(null);
const [listenBrand, setListenBrand] = useState(false);
const [brand, setBrand] = useState<Brand>(null);
/** Listen for auth state changes */
useEffect(() => {
const authListener = auth().onAuthStateChanged(result => {
setUserAuth(result);
if (initializing && !listenUserAuth) {
setInitializing(false);
setListenUserAuth(true);
setListenUser(true);
setListenBrand(true);
}
});
return () => {
if (authListener) {
console.log('removing auth state listener');
authListener();
}
};
}, [initializing, listenUserAuth]);
/** Listen for user auth changes */
useEffect(() => {
let userAuthListener: () => void;
if (listenUserAuth) {
userAuthListener = auth().onUserChanged(result => {
setUserAuth(result);
});
}
return () => {
if (userAuthListener) {
console.log('removing user auth listener');
userAuthListener();
}
};
}, [listenUserAuth]);
/** Listen for user document changes */
useEffect(() => {
let userListener: () => void;
if (listenUser) {
if (!userAuth) {
return;
}
console.log('listening user document');
userListener = firestore()
.collection('users')
.doc(userAuth.uid)
.onSnapshot(querySnapshot => {
console.log('User querySnapshot: ', querySnapshot.data());
setUser(querySnapshot.data());
});
}
return () => {
if (userListener) {
console.log('removing user document listener');
userListener();
}
};
}, [listenUser, userAuth]);
/** Listen for brand document changes */
useEffect(() => {
let brandListener: () => void;
if (listenBrand) {
if (!userAuth) {
return;
}
console.log('listening brand document');
brandListener = firestore()
.collection('brands')
.doc('31uOUtUkVYg8z953UdxS')
.onSnapshot(querySnapshot => {
console.log('Brand querySnapshot: ', querySnapshot.data());
setBrand(querySnapshot.data());
});
}
return () => {
if (brandListener) {
console.log('removing brand document listener');
brandListener();
}
};
}, [listenBrand, userAuth]);
if (initializing) {
return (
<View style={{flex: 1, justifyContent: 'center'}}>
<ActivityIndicator size="large" color="#000" />
</View>
);
}
function container(children: ReactNode | ReactNode[]) {
return <PaperProvider theme={theme}>{children}</PaperProvider>;
}
return container(
userAuth && user && brand ? (
<Context.Provider value={{userAuth, user, brand}}>
<SignedInStack />
</Context.Provider>
) : (
<SignedOutStack />
)
);
}
export default App;
在另一个组件中,当用户注销时,所有侦听器都在重新侦听并多次删除自身。
日志:
这将对Firebase添加不必要的读取和写入,这会增加成本。
我是使用 useEffect 的新手,我很确定自己做错了什么。我不完全了解useEffect需要开始监听用户文档和品牌文档一次并删除一次监听器所需的依赖项。在这样做之前,我尝试阅读,我认为我做对了。
我的目标是: