React Native Drawer导航下如何重置组件状态为空字符串?
问题描述
在React Native Navigation中,Stack导航下DetailsScreen能正常将title和uri更新为route.params对应值,但Drawer导航下,useState仅在首次初始化时生效。返回DetailsScreen时,输入框显示上次输入的值,而非最新的route.params数据,仿佛useState只执行了一次。
相关代码
import React, { useState, useEffect } from 'react'; import { Button, Text, TextInput, View } from 'react-native'; import { styles } from '../Styles'; import { store } from '../data/SignalSorage'; export default function DetailsScreen({ navigation, route }) { console.log(`Route title:${route.params.title}`); console.log(`Route uri:${route.params.uri}`); const [title, setTitle] = useState(route.params.title); const [uri, setUri] = useState(route.params.uri); useEffect(() => { setTitle(''); }, []); console.log(`DetailsScreen title:${title}, uri:${uri}`); return ( <View style={styles.container}> <View> <Text style={styles.input_title}>Title:</Text> <TextInput placeholderTextColor="#888" style={styles.input} placeholder="enter title here..." onChangeText={(value) => { setTitle(value); }} value={title} /> </View> <View> <Text style={styles.input_title}>Uri:</Text> <TextInput placeholderTextColor="#888" style={styles.input} placeholder="enter signal here..." onChangeText={(value) => { setUri(value); }} value={uri} /> </View> <View> <Button title='Save element' onPress={() => { store.save({ key: store.getLastKey() + 1, title: title, uri: uri }); console.log(`title=${title}, uri=${uri}`); navigation.navigate({ name: 'HomeScreen', merge: true, }); }} /> </View> </View> ); }
日志信息
[Info] 01-20 10:26:07.072 5733 5811 I ReactNativeJS: Route title: 01-20 10:26:07.072 5733 5811 I ReactNativeJS: Route uri: [Info] 01-20 10:26:07.073 5733 5811 I ReactNativeJS: DetailsScreen title:Test, uri: [Info] 01-20 10:26:07.153 5733 5811 I ReactNativeJS: DetailsScreen focused.
解决方案
核心原因
useState的初始化参数仅在组件首次挂载时生效,后续组件重新渲染(路由参数变化、从其他页面返回)时,不会重新执行useState(route.params.title)更新状态。- 代码中存在一个空依赖的
useEffect,会在组件挂载时强制清空title,干扰初始值设置。 - Drawer导航默认会保留页面实例在内存中(不会卸载),返回时不会重置状态;而Stack导航在部分场景下会重新挂载组件,因此表现不同。
修复步骤
移除干扰的空依赖
useEffect
删掉这段会清空title的代码:// 移除该代码块 useEffect(() => { setTitle(''); }, []);监听
route.params变化,同步更新状态
添加依赖route.params的useEffect,当路由参数更新时手动同步状态:useEffect(() => { setTitle(route.params.title || ''); setUri(route.params.uri || ''); }, [route.params]);加入
|| ''是为了避免route.params字段为undefined时,输入框显示异常。修复后完整代码
import React, { useState, useEffect } from 'react'; import { Button, Text, TextInput, View } from 'react-native'; import { styles } from '../Styles'; import { store } from '../data/SignalSorage'; export default function DetailsScreen({ navigation, route }) { console.log(`Route title:${route.params.title}`); console.log(`Route uri:${route.params.uri}`); const [title, setTitle] = useState(route.params.title || ''); const [uri, setUri] = useState(route.params.uri || ''); // 监听路由参数变化,同步更新状态 useEffect(() => { setTitle(route.params.title || ''); setUri(route.params.uri || ''); }, [route.params]); console.log(`DetailsScreen title:${title}, uri:${uri}`); return ( <View style={styles.container}> <View> <Text style={styles.input_title}>Title:</Text> <TextInput placeholderTextColor="#888" style={styles.input} placeholder="enter title here..." onChangeText={setTitle} value={title} /> </View> <View> <Text style={styles.input_title}>Uri:</Text> <TextInput placeholderTextColor="#888" style={styles.input} placeholder="enter signal here..." onChangeText={setUri} value={uri} /> </View> <View> <Button title='Save element' onPress={() => { store.save({ key: store.getLastKey() + 1, title, uri }); console.log(`title=${title}, uri=${uri}`); navigation.navigate({ name: 'HomeScreen', merge: true, }); }} /> </View> </View> ); }
关键知识点
useState初始值仅在组件首次挂载时读取,后续渲染不会自动重置。- 外部依赖数据(如路由参数)变化时,需通过
useEffect监听并手动更新状态。 - React Native不同导航类型的组件生命周期策略不同,Drawer导航默认保留页面实例,状态不会随页面切换重置。
内容的提问来源于stack exchange,提问作者Papp Zoltán
相关产品推荐
相关产品推荐

