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

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.

解决方案

核心原因

  1. useState的初始化参数仅在组件首次挂载时生效,后续组件重新渲染(路由参数变化、从其他页面返回)时,不会重新执行useState(route.params.title)更新状态。
  2. 代码中存在一个空依赖的useEffect,会在组件挂载时强制清空title,干扰初始值设置。
  3. Drawer导航默认会保留页面实例在内存中(不会卸载),返回时不会重置状态;而Stack导航在部分场景下会重新挂载组件,因此表现不同。

修复步骤

  1. 移除干扰的空依赖useEffect
    删掉这段会清空title的代码:

    // 移除该代码块
    useEffect(() => {
        setTitle('');
    }, []);
    
  2. 监听route.params变化,同步更新状态
    添加依赖route.params的useEffect,当路由参数更新时手动同步状态:

    useEffect(() => {
        setTitle(route.params.title || '');
        setUri(route.params.uri || '');
    }, [route.params]);
    

    加入|| ''是为了避免route.params字段为undefined时,输入框显示异常。

  3. 修复后完整代码

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:55:29