我已经实现了领域设备同步,我使用电子邮件/密码身份验证方法登录。我按照模板中提供的步骤,我已经将导航容器放置在领域的AppProvider和用户提供程序组件的顶层。当用户未登录时,我将显示登录页面。但是,我无法移动到正在从登录页面导航的注册页面。
App.tsx代码
import "react-native-gesture-handler";
import { NavigationContainer } from "@react-navigation/native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import NativeStack from "./src/routes/NativeStack";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { PaperProvider } from "react-native-paper";
import { AppProvider, UserProvider } from "@realm/react";
import { appId, baseUrl } from "./atlasConfig.json";
import Login from "./src/screens/authScreen/Login";
import realmContext from "./src/data/dbContext";
import Loading from "./src/screens/loadingScreen/Loading";
export default function App() {
// Getting Realm Provider
const { RealmProvider } = realmContext;
return (
<PaperProvider>
<SafeAreaProvider>
<GestureHandlerRootView style={{ flex: 1 }}>
<NavigationContainer>
<AppProvider id={appId} baseUrl={baseUrl}>
<UserProvider fallback={Login}>
<RealmProvider
sync={{
flexible: true,
onError: (_, error) => {
console.log(error);
},
initialSubscriptions: {
update(subs, realm) {
subs.add(realm.objects("Company")),
subs.add(realm.objects("Purchase")),
subs.add(realm.objects("Payment"));
},
},
}}
fallback={Loading}
>
<NativeStack />
</RealmProvider>
</UserProvider>
</AppProvider>
</NavigationContainer>
</GestureHandlerRootView>
</SafeAreaProvider>
</PaperProvider>
);
}
字符串
登录.tsx的代码
import Realm from "realm";
import {
Keyboard,
NativeSyntheticEvent,
StyleSheet,
TextInputChangeEventData,
TouchableWithoutFeedback,
View,
} from "react-native";
import React, { useCallback, useState } from "react";
import { StackActions, useNavigation } from "@react-navigation/native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Button, Text, TextInput } from "react-native-paper";
import { useApp } from "@realm/react";
const Login = () => {
// Realm App Context
const app = useApp();
// Navigation
const nav = useNavigation();
// Form input variables
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
// Toggle Password Visibility
const [passwordVisibility, setPasswordVisibility] = useState(true);
// Action Handlers
const formClear = () => {
setEmail("");
setPassword("");
setPasswordVisibility(true);
};
const registerHandler = () => {
nav.dispatch(StackActions.replace("Register"));
formClear();
};
const loginHandler = useCallback(async () => {
const creds = Realm.Credentials.emailPassword({ email, password });
await app.logIn(creds);
formClear();
}, [app, email, password]);
return (
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
style={styles.containerWrapper}
>
<SafeAreaView style={styles.containerWrapper}>
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text variant="titleLarge" style={styles.headerLabel}>
Register
</Text>
</View>
<View>
<TextInput
label="Email"
placeholder="Email"
value={email}
autoCapitalize="none"
onChange={(e: NativeSyntheticEvent<TextInputChangeEventData>) => {
setEmail(e.nativeEvent.text);
}}
/>
<TextInput
label="Password"
placeholder="Password"
value={password}
autoCapitalize="none"
secureTextEntry={passwordVisibility}
onChange={(e: NativeSyntheticEvent<TextInputChangeEventData>) => {
setPassword(e.nativeEvent.text);
}}
right={
<TextInput.Icon
icon="eye"
onPress={() => {
setPasswordVisibility((previousState) => !previousState);
}}
/>
}
/>
</View>
<View style={styles.buttonContainer}>
<Button mode="contained" onPress={loginHandler}>
Login
</Button>
<Button mode="outlined" onPress={registerHandler}>
Don't have an Account? Register
</Button>
</View>
</View>
</SafeAreaView>
</TouchableWithoutFeedback>
);
};
export default Login;
const styles = StyleSheet.create({
containerWrapper: {
flex: 1,
},
container: {
flex: 1,
},
headerContainer: {},
headerLabel: {},
inputContainer: {
gap: 20,
},
buttonContainer: {},
button: {},
});
型
注册.tsx的代码
import Realm from "realm";
import {
Alert,
Keyboard,
NativeSyntheticEvent,
StyleSheet,
TextInputChangeEventData,
TouchableWithoutFeedback,
View,
} from "react-native";
import React, { useCallback, useState } from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import { Button, Text, TextInput } from "react-native-paper";
import { StackActions, useNavigation } from "@react-navigation/native";
import { useApp } from "@realm/react";
const Register = () => {
// App Context for Realm
const app = useApp();
// Navigation
const nav = useNavigation();
// Form input variables
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
// Toggle Password Visibility
const [passwordVisibility, setPasswordVisibility] = useState(true);
const [confirmPasswordVisibility, setConfirmPasswordVisibility] =
useState(true);
// Action Handlers
const formClear = () => {
setEmail("");
setPassword("");
setConfirmPassword("");
setPasswordVisibility(true);
setConfirmPasswordVisibility(true);
};
const signIn = useCallback(async () => {
const creds = Realm.Credentials.emailPassword({ email, password });
await app.logIn(creds);
}, [app, email, password]);
const registerHandler = useCallback(async () => {
try {
await app.emailPasswordAuth.registerUser({ email, password });
await signIn();
formClear();
} catch (error: any) {
Alert.alert(`Failed to Register: ${error?.message}`);
}
}, [signIn, app, email, password]);
const loginHandler = () => {
nav.dispatch(StackActions.replace("Login"));
formClear();
};
return (
<TouchableWithoutFeedback
onPress={Keyboard.dismiss}
style={styles.containerWrapper}
>
<SafeAreaView style={styles.containerWrapper}>
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text variant="displayLarge" style={styles.headerLabel}>
Register
</Text>
</View>
<View style={styles.formContainer}>
<TextInput
label="Email"
placeholder="Email"
value={email}
autoCapitalize="none"
onChange={(e: NativeSyntheticEvent<TextInputChangeEventData>) => {
setEmail(e.nativeEvent.text);
}}
/>
<TextInput
label="Password"
placeholder="Password"
value={password}
autoCapitalize="none"
secureTextEntry={passwordVisibility}
onChange={(e: NativeSyntheticEvent<TextInputChangeEventData>) => {
setPassword(e.nativeEvent.text);
}}
right={
<TextInput.Icon
icon="eye"
onPress={() => {
setPasswordVisibility((previousState) => !previousState);
}}
/>
}
/>
<TextInput
label="Confirm Password"
placeholder="Re-Enter Password"
value={confirmPassword}
autoCapitalize="none"
secureTextEntry={confirmPasswordVisibility}
onChange={(e: NativeSyntheticEvent<TextInputChangeEventData>) => {
setConfirmPassword(e.nativeEvent.text);
}}
right={
<TextInput.Icon
icon="eye"
onPress={() => {
setConfirmPasswordVisibility(
(previousState) => !previousState
);
}}
/>
}
/>
</View>
<View style={styles.buttonContainer}>
<Button mode="contained" onPress={registerHandler}>
Register
</Button>
<Button mode="outlined" onPress={loginHandler}>
Already have an Account? Login
</Button>
</View>
</View>
</SafeAreaView>
</TouchableWithoutFeedback>
);
};
export default Register;
const styles = StyleSheet.create({
containerWrapper: {
flex: 1,
},
container: {
flex: 1,
},
headerContainer: {
height: 80,
},
headerLabel: {},
inputContainer: {
gap: 20,
},
buttonContainer: {},
button: {},
formContainer: {
flex: 1,
gap: 20,
},
});
型
我试着将导航容器移到领域提供程序和应用程序提供程序的上方,看看导航对象是否在之后提供。到目前为止还没有解决方案。
1条答案
按热度按时间hujrc8aj1#
我会在稍后的时间发布这个答案。在fallback下的Realm的UserProvider需要一个单独的导航堆栈设置,正是因为这个原因,我遇到了未初始化导航对象错误的问题。
我只需要在回退选项中添加另一个单独的导航堆栈和一个单独的导航容器来解决这个问题。