【问题标题】:React Native Hooks and Authentication flowReact Native Hooks 和身份验证流程
【发布时间】: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


【解决方案1】:

import React, { useContext } from 'react'
import AuthContext from '../path/to/context'

class Login extends React.Component {
  handleLogin = () => {
    const { signIn } = this.props
    const {navigation} = this.props;
    const {email, password} = this.state;
    
    keyboard.dismiss()
    
    let errors = []
    
    if (email !== VALID_EMAIL) {
      errors.push('email');
    }
    if (password !== VALID_PASSWORD) {
      errors.push('password');
    }
    
    if (errors.length) {
      this.setState({ errors })
    }
    else {
      const callback = () => {
        this.setState({ loading: false })
      }
      
      this.setState(prevState => { 
        signIn()
        return { ...prevState, loading: true }
      }), callback)
    }
  }
}

const LoginWithContext = props => {
  const { signIn } = useContext(AuthContext)
  return (
    <Login signIn={signIn} />
  )
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【讨论】:

  • 我已经用建议的更新更新了我的问题,但仍然无法正常工作
  • 很高兴听到它对您有帮助
猜你喜欢
  • 2020-12-31
  • 2021-02-23
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
相关资源
最近更新 更多