React Native条件渲染切换组件时setState未定义报错如何解决
报错解决&逻辑实现方案
报错原因
你当前定义的App是函数组件,this.setState是类组件专属的状态更新API,函数组件不存在this实例指向,也没有内置的setState方法,所以触发了该报错。同时你直接声明state = {}的写法在函数组件中不会触发重渲染,状态变更无法同步到视图。
修复步骤
- 导入React内置的
useStateHook管理状态:
// 把原有的React导入替换为下面的写法 import React, { useState } from 'react';
- 替换原有的state声明,使用useState定义状态变量和更新方法:
// 删掉原来的state = {screenwhich:true}这段,替换为下面的代码 const [screenWhich, setScreenWhich] = useState(true);
- 修改切换逻辑,直接调用useState返回的更新方法修改状态:
const changeScreenToRegister = () => { setScreenWhich(false); } // 可以补充切换回Login的方法,给注册按钮用 const changeScreenToLogin = () => { setScreenWhich(true); }
- 调整渲染逻辑,使用状态变量判断渲染组件:
// 条件渲染部分修改为 { screenWhich ? <Login /> : <Register /> } // 注册按钮的onPress也可以替换为切换回Login的逻辑 <TouchableHighlight style={styles.register} onPress={changeScreenToLogin}>
完整可运行的App.js修改示例
import { StatusBar } from 'expo-status-bar'; import React, { useState } from 'react'; import { StyleSheet, Text, View, Alert,Button,TextInput ,TouchableWithoutFeedback,Image, ImageBackground, SafeAreaView,TouchableHighlight } from 'react-native'; import Login from './screens/Login'; import Register from './screens/Register'; export default function App() { const [screenWhich, setScreenWhich] = useState(true); const changeToRegister = () => { setScreenWhich(false); } const changeToLogin = () => { setScreenWhich(true); } return ( <ImageBackground source={require('./assets/background.jpg')} style={styles.background}> <Text>当前页面:{screenWhich ? '登录页' : '注册页'}</Text> { screenWhich ? <Login /> : <Register />} <Image style={styles.logo} source={require('./assets/logo-red.png')} /> <TouchableHighlight style={styles.login} onPress={changeToRegister}> <View style={styles.login} > <Text style={styles.loginBtnTitle}>Login</Text> </View> </TouchableHighlight> <TouchableHighlight style={styles.register} onPress={changeToLogin}> <View style={styles.register} > <Text style={styles.registerBtnTitle} >Register</Text> </View> </TouchableHighlight> </ImageBackground> ); } // styles部分不需要修改,保持原样即可 const styles = StyleSheet.create({ container: { flex: 1, backgroundColor:'#fff', alignItems: 'center', justifyContent: 'center', alignItems:"center" }, row:{ display: "-webkit-box", display:" -ms-flexbox", display: "flex", flexWrap: "wrap", marginRight: "-15px", marginLeft: "-15px", }, input: { display: "flex", width: "100%", fontSize: 20, lineHeight: 15.5, color: "#495057", backgroundColor: "#fff", borderColor: "#ced4da", borderRadius: 0.25, }, background:{ flex:1, justifyContent:"flex-end", alignItems:"center", }, logo:{ width:100, height:100, position:"absolute",top:100 }, login: { backgroundColor:"tomato", width:"100%", height:70, alignItems:"center" }, register: { backgroundColor:"dodgerblue", width:"100%", height:70, alignItems:"center", }, loginBtnTitle:{ fontSize:30, top:20, color:"white", position:"relative" }, registerBtnTitle:{ fontSize:30, top:20, color:"white", position:"relative" } });
后续表单开发适配
如果需要在Login、Register组件内部控制页面切换,可以把setScreenWhich作为props传递给子组件,子组件内直接调用该方法即可修改父组件的状态,完成页面切换。
内容的提问来源于stack exchange,提问作者Mohammad Fahad
相关产品推荐
相关产品推荐

