You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native条件渲染失效,咨询代码修改实现登录注册切换逻辑

修复React Native登录/注册/账户管理的条件渲染流程

问题根源

  1. 原代码用多个布尔状态(showRegisterForm/afterRegister/afterLogin)组合控制视图,逻辑嵌套复杂,容易出现状态冲突导致显示异常。
  2. 登录逻辑中无论请求是否成功,都直接设置afterLogin=true,不符合预期流程。
  3. 注册成功后仅设置afterRegister=true,未重置注册表单状态,无法正确切回登录视图。

修改方案

改用单一状态currentView控制当前显示的视图,取值为'login'/'register'/'account',简化状态逻辑;同时修正登录、注册的状态切换逻辑,确保流程符合预期。

修改后的完整代码

import { StyleSheet, Button } from 'react-native';
import React, { useState } from 'react';
import { View, TextInput, TouchableOpacity, Linking } from 'react-native';
import { Text } from '../../components/Themed';
import axios from 'axios';
import { Constants } from '../../constants/Constants';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function TabOneScreen() {
  // 登录表单状态
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")

  // 注册表单状态
  const [firstName, setFirstName] = useState("")
  const [lastName, setLastName] = useState("")
  const [userEmail, setUserEmail] = useState("")
  const [userPassword, setUserPassword] = useState("")
  const [confirmPassword, setConfirmPassword] = useState("")
  const [stripeConnectAcctId, setStripeConnectAcctId] = useState("")

  // 控制当前显示的视图:'login' | 'register' | 'account'
  const [currentView, setCurrentView] = useState('login')

  const subdomain = Constants.Subdomain;

  const onPressLogin = async () => {
    try {
      const req_json2 = { username: email, password: password, grant_type: 'password' }
      const headers2 = {
        headers: {
          "Accept": "*/*",
          "Connection": "keep-alive",
          "Accept-Encoding": "gzip, deflate, br",
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control": "no-cache",
          "Host": `${subdomain}.conveyor.cloud`
        }
      };

      const resp = await axios.post(`https://${subdomain}.conveyor.cloud/token`, req_json2, headers2);
      const token = resp.data.access_token;

      if (token && token !== "") {
        console.log("auth_token: " + token);
        await AsyncStorage.setItem('auth_token', token);
        await AsyncStorage.setItem('senderEmail', email);
        // 登录成功,切换到账户管理视图
        setCurrentView('account')
      }
    } catch (err) {
      console.error('登录失败:', err)
      // 可添加错误提示逻辑
    }
  }

  const stripeOnboarding = async () => {
    try {
      const auth_token = await AsyncStorage.getItem('auth_token');
      const headers = {
        headers: {
          "Authorization": `Bearer ${auth_token}`,
          "Accept": "*/*",
          "Connection": "keep-alive",
          "Accept-Encoding": "gzip, deflate, br",
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control": "no-cache",
          "Host": `${subdomain}.conveyor.cloud`
        }
      };

      const resp = await axios.post(`https://${subdomain}.conveyor.cloud/Home/CreateStripeAccount`, {}, headers);
      console.log(resp.data.connectedAccountId, resp.data.onboardingUrl)

      if (resp) {
        setStripeConnectAcctId(resp.data.connectedAccountId);
        const senderEmail = await AsyncStorage.getItem('senderEmail');
        const req_json = { email: senderEmail, stripeConnectedAcctId: resp.data.connectedAccountId };

        const headers2 = {
          headers: {
            "Authorization": `Bearer ${auth_token}`,
            "Accept": "*/*",
            "Connection": "keep-alive",
            "Accept-Encoding": "gzip, deflate, br",
            "Content-Type": "application/x-www-form-urlencoded",
            "Cache-Control": "no-cache",
            "Host": `${subdomain}.conveyor.cloud`
          }
        };

        await axios.post(`https://${subdomain}.conveyor.cloud/Account/SaveStripeAcctId`, req_json, headers2);

        if (await Linking.canOpenURL(resp.data.onboardingUrl)) {
          await Linking.openURL(resp.data.onboardingUrl);
        }
      }
    } catch (err) {
      console.error('Stripe连接失败:', err)
    }
  }

  const submitRegistrationForm = async () => {
    try {
      const req_json = {
        FirstName: firstName,
        LastName: lastName,
        Email: userEmail,
        Password: userPassword,
        ConfirmPassword: confirmPassword
      }

      const headers = {
        headers: {
          "Accept": "*/*",
          "Connection": "keep-alive",
          "Accept-Encoding": "gzip, deflate, br",
          "Content-Type": "application/x-www-form-urlencoded",
          "Cache-Control": "no-cache",
          "Host": `${subdomain}.conveyor.cloud`
        }
      };

      await axios.post(`https://${subdomain}.conveyor.cloud/Account/Register`, req_json, headers);
      // 注册成功,重置表单并切回登录视图
      setFirstName("")
      setLastName("")
      setUserEmail("")
      setUserPassword("")
      setConfirmPassword("")
      setCurrentView('login')
    } catch (err) {
      console.error('注册失败:', err)
      // 可添加错误提示逻辑
    }
  }

  // 根据currentView渲染对应组件
  const renderView = () => {
    switch (currentView) {
      case 'login':
        return (
          <View style={styles.container}>
            <View style={styles.inputView}>
              <TextInput
                style={styles.inputText}
                placeholder="Email"
                placeholderTextColor="#003f5c"
                onChangeText={(text) => setEmail(text)}
                value={email}
              />
            </View>
            <View style={styles.inputView}>
              <TextInput
                style={styles.inputText}
                secureTextEntry
                placeholder="Password"
                placeholderTextColor="#003f5c"
                onChangeText={(text) => setPassword(text)}
                value={password}
              />
            </View>
            <View style={styles.inputView}>
              <TouchableOpacity
                onPress={onPressLogin}
                style={styles.loginBtn}>
                <Text>Log in.</Text>
              </TouchableOpacity>
            </View>
            <View>
              <Button
                onPress={() => setCurrentView('register')}
                style={styles.registerBtn}
                title='Register'
              />
            </View>
          </View>
        )
      case 'register':
        return (
          <View style={styles.container}>
            <Text>Registration Form.</Text>
            <TextInput placeholder='First name' onChangeText={text => setFirstName(text)} style={styles.registerFormField} value={firstName}></TextInput>
            <TextInput placeholder='Last name' onChangeText={text => setLastName(text)} style={styles.registerFormField} value={lastName}></TextInput>
            <TextInput placeholder='Email address' onChangeText={text => setUserEmail(text)} style={styles.registerFormField} value={userEmail}></TextInput>
            <TextInput placeholder='Password' onChangeText={text => setUserPassword(text)} style={styles.registerFormField} secureTextEntry value={userPassword}></TextInput>
            <TextInput placeholder='Confirm password' onChangeText={text => setConfirmPassword(text)} style={styles.registerFormField} secureTextEntry value={confirmPassword}></TextInput>
            <Button onPress={submitRegistrationForm} title='Register'/>
            {/* 可选:添加返回登录按钮 */}
            <Button onPress={() => setCurrentView('login')} title='Back to Login' style={{ marginTop: 10 }}/>
          </View>
        )
      case 'account':
        return (
          <View style={styles.container}>
            <Text>Manage Account.</Text>
            <Button onPress={stripeOnboarding} title='Connect with Stripe'/>
          </View>
        )
      default:
        return null
    }
  }

  return renderView()
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    padding: 20
  },
  inputView:{
    width:"80%",
    backgroundColor:"#3AB4BA",
    borderRadius:25,
    height:50,
    marginBottom:20,
    justifyContent:"center",
    padding:20
  },
  inputText:{
    height:50,
    color:"white"
  },
  loginBtn: {
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%'
  },
  registerBtn: {
    marginTop:35,
    padding:8,
    borderColor:'black',
    borderWidth:2,
    borderRadius:5
  },
  registerFormField: {
    width: '100%',
    margin:8,
    borderColor: 'black',
    borderWidth: 2,
    padding:10,
    borderRadius: 5
  }
});

关键修改点

  • 用currentView单一状态替代多个布尔状态,逻辑更清晰,避免状态冲突。
  • 登录逻辑中仅在成功获取token后切换到账户视图,添加错误捕获。
  • 注册成功后重置表单输入值,并切换回登录视图。
  • 拆分渲染逻辑到renderView函数,用switch-case实现条件渲染,可读性更强。
  • 给TextInput添加value属性,确保表单输入受控。
  • 优化Stripe逻辑中的AsyncStorage调用,添加await确保获取到token。

内容的提问来源于stack exchange,提问作者xccelerated99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:25:57