React Native子组件onChangeText触发时修改父组件state报setName未定义如何解决
报错原因及修复方案
核心问题梳理
- 你在父组件中嵌入的
<NameScreen setName={setName} />被设置了display: none隐藏,如果你是通过navigation.navigate跳转打开NameScreen页面,跳转生成的是全新的组件实例,没有接收到父组件传递的setName属性,所以触发onChangeText时会提示setName不是函数。 - 子组件自身存在语法错误:代码中多处使用未定义的
text变量,即便setName传递正常也会触发报错。
修复方案
优先推荐采用条件渲染控制姓名填写页的显隐,无需路由跳转即可正常传递状态方法,修改后的代码如下:
父组件代码
const ProfileCreationScreen = () => { // 给name设置初始空字符串,避免输入框受控属性异常 const [name, setName] = useState('') // 新增状态控制姓名填写页显隐 const [showNameScreen, setShowNameScreen] = useState(false) const userSignup = async () => { try { // 补充await关键字,不然catch捕获不到异步抛出的错误 await firestore().collection('users').doc("androiduser_mobile89").set({ name: name, }); alert("创建成功") } catch (error) { alert(error); } }; return ( <SafeAreaView> {!showNameScreen ? ( <> <Text>创建你的账号</Text> <Button mode="contained" onPress={() => setShowNameScreen(true)} > 填写姓名 </Button> <Button mode="contained" onPress={userSignup} disabled={!name} > 注册 </Button> </> ) : ( // 显隐控制下的组件可以正常接收传递的属性 <NameScreen setName={setName} name={name} goBack={() => setShowNameScreen(false)} /> )} </SafeAreaView> ) }
子组件代码
export const NameScreen = ({ setName, name, goBack }) => { return ( <KeyboardAvoidingView enabled behavior="padding" style={styles.container}> <View> <Text style={styles.text}>全名</Text> <TextInput style={styles.textField} label="请输入你的全名" underlineColor="#FF0074" outlineColor="red" // 绑定父组件传递的name属性 value={name} onChangeText={(text) => setName(text)} /> <Button mode="contained" style={styles.btn} onPress={goBack}> 下一步 </Button> </View> </KeyboardAvoidingView> );
特殊说明
如果你必须使用路由跳转打开NameScreen,不能直接在路由参数中传递setState方法(路由参数会被序列化,函数无法正常传递),需要使用Context、Zustand等全局状态管理方案共享name状态,或者在姓名填写完毕后通过路由参数把输入的内容回传给父组件。
内容的提问来源于stack exchange,提问作者sudhansu bhattarai
相关产品推荐
相关产品推荐

