【发布时间】:2020-08-26 20:06:03
【问题描述】:
我目前正在为我的 React Native 应用程序设置身份验证流程,我遇到了以下问题。
我的导航屏幕是这样的
export default CreateStack = () => {
const [isLoading, setIsLoading] = React.useState(true);
const [userToken, setUserToken] = React.useState(null);
const authContext = React.useMemo(() => {
return {
signIn: () => {
setIsLoading(false);
setUserToken('asdf');
},
signUp: () => {
setIsLoading(false);
setUserToken('asdf');
},
signOut: () => {
setIsLoading(false);
setUserToken(null);
},
};
}, []);
React.useEffect(() => {
setTimeout(() => {
setIsLoading(false);
}, 1000);
}, []);
if (isLoading) {
return <LoadingScreen />;
}
return (
<AuthContext.Provider value={authContext}>
<NavigationContainer>
{userToken ? (
<Stack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={Browser}>
<Stack.Screen name="Browser" component={TabsScreen} />
<Stack.Screen name="PreScreen" component={PreScreen} />
<Stack.Screen name="Player" component={Player} />
</Stack.Navigator>
) : (
<AuthStack.Navigator
screenOptions={{headerShown: false}}
initialRouteName={RegisterLogin}>
<AuthStack.Screen name="RegisterLogin" component={RegisterLogin} />
<AuthStack.Screen name="Login" component={Login} />
<AuthStack.Screen name="Register" component={Register} />
</AuthStack.Navigator>
)}
</NavigationContainer>
</AuthContext.Provider>
);
};
AuthContext:
import React from 'react';
export const AuthContext = React.createContext();
当我尝试从我的登录屏幕中的导航屏幕访问 singIn 函数时,我收到无效挂钩调用的错误。
我的登录屏幕由以下类组成
class Login extends Component {
state = {
email: VALID_EMAIL,
password: VALID_PASSWORD,
errors: [],
loading: false,
};
handleLogin() {
const {signIn} = React.useContext(AuthContext);
const {navigation} = this.props;
const {email, password} = this.state;
let errors = [];
Keyboard.dismiss();
this.setState({loading: true});
if (email !== VALID_EMAIL) {
errors.push('email');
}
if (password !== VALID_PASSWORD) {
errors.push('password');
}
this.setState({errors, loading: false});
if (!errors.length) {
signIn();
}
}
render() {
const {navigation} = this.props;
const {loading, errors} = this.state;
const hasErrors = (key) => (errors.includes(key) ? styles.hasErrors : null);
return (
<View style={styles.mainContainerView}>
<StatusBar barStyle="light-content" />
<NavigationBarDown title="LogIn" />
<TextInput
style={[styles.TextInput, hasErrors('email')]}
label="Email"
error={hasErrors('email')}
placeholder="Email Adress"
autoCapitalize="none"
autoCorrect={false}
onChangeText={(text) => this.setState({email: text})}
/>
<TextInput
label="Password"
placeholder="Password"
error={hasErrors('password')}
style={[styles.TextInput, hasErrors('password')]}
onChangeText={(text) => this.setState({password: text})}
/>
<TouchableOpacity
style={styles.singInButton}
gradient
onPress={() => this.handleLogin()}>
{loading ? (
<ActivityIndicator size="small" color="white" />
) : (
<Text style={styles.logInText}>Login</Text>
)}
</TouchableOpacity>
<Text>Dont have an account ?</Text>
<TouchableOpacity>
<Text>Register here in here</Text>
</TouchableOpacity>
</View>
);
}
}
export default Login;
我在这里被困了几天,所以欢迎任何帮助
经过一些更新,我出来了这个
import React, {useContext} from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StatusBar,
Keyboard,
KeyboardAvoidingView,
} from 'react-native';
import styles from './style';
import NavigationBarDown from '../../components/NavigationBardown/NavigationBarDown';
import {AuthContext} from '../../components/Navigation/context';
import login from './action';
const VALID_EMAIL = 'c';
const VALID_PASSWORD = '2';
const EMPTY = '';
class Login extends React.Component {
state = {
email: VALID_EMAIL,
password: VALID_PASSWORD,
errors: [],
loading: false,
};
handleLogin = () => {
const {navigation} = this.props;
const {email, password} = this.state;
let errors = [];
Keyboard.dismiss();
this.setState({loading: true});
if (email !== VALID_EMAIL) {
errors.push('email');
}
if (password !== VALID_PASSWORD) {
errors.push('password');
}
this.setState({errors, loading: false});
if (!errors.length) {
this.props.signIn;
}
};
render() {
const {navigation} = this.props;
const {loading, errors} = this.state;
const hasErrors = (key) => (errors.includes(key) ? styles.hasErrors : null);
return (
<View style={styles.mainContainerView}>
<StatusBar barStyle="light-content" />
<NavigationBarDown title="LogIn" />
<TextInput
style={[styles.TextInput, hasErrors('email')]}
label="Email"
error={hasErrors('email')}
placeholder="Email Adress"
autoCapitalize="none"
autoCorrect={false}
onChangeText={(text) => this.setState({email: text})}
/>
<TextInput
label="Password"
placeholder="Password"
error={hasErrors('password')}
style={[styles.TextInput, hasErrors('password')]}
onChangeText={(text) => this.setState({password: text})}
/>
<TouchableOpacity
style={styles.singInButton}
gradient
onPress={() => this.handleLogin()}>
{loading ? (
<ActivityIndicator size="small" color="white" />
) : (
<Text style={styles.logInText}>Login</Text>
)}
</TouchableOpacity>
<Text>Dont have an account ?</Text>
<TouchableOpacity>
<Text>Register here in here</Text>
</TouchableOpacity>
</View>
);
}
}
const LoginWithContext = (props) => {
const {signIn} = useContext(AuthContext);
return <Login signIn={signIn} />;
};
export default LoginWithContext;
现在还是不行
【问题讨论】:
-
handleLogin() 函数在类组件中。你不能在类组件中调用反应钩子。解决方法是创建一个Login函数组件,在组件中使用Context,并将上下文传递给你的Login Class Component
-
那么结果如何?
-
@Kaslie 嗨,所以我设法创建了另一个功能组件:const login = (component) => { return function WrappedComponent(props) { const {signIn} = React.useContext(AuthContext);返回登录(); }; };导出默认登录;现在我有点困惑我应该如何在 handleLogin() 函数中调用。我尝试调用而不是 singIn 新创建的登录功能,但没有运气
-
也是在handleLogin的开头我声明了:const {signIn} = this.props.login;我将类导出为以下导出默认 singIn(Login);我知道我做错了什么我对钩子真的不熟悉
-
我在下面添加了我的答案
标签: reactjs react-native navigation react-hooks react-navigation-stack