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

React Native文本输入框输入后恢复初始状态问题解决求助

问题原因及解决方法

核心问题:无依赖的useEffect导致输入被覆盖

你的useEffect未设置依赖数组,这会导致组件每次重新渲染时都会执行_readdiary。当你在TextInput输入内容时,setTitle触发组件渲染,紧接着_readdiary会从AsyncStorage读取旧数据并重置title,最终导致输入框回到初始状态。

具体修复步骤

1. 给useEffect添加正确的依赖数组

修改useEffect,仅在组件初始化或dateString变化时读取数据:

useEffect(() => {
  _readdiary();
}, [dateString]); // 仅当dateString改变时执行

2. 修复_savediary的状态异步问题

setTitle是异步操作,直接调用setTitle(text)后使用title值存数据,拿到的会是更新前的旧值。应该直接将输入的text作为参数传入:

const handleChangeTitle = (text) => {
  setTitle(text);
  _savediary(text); // 直接传递最新输入的text
};

const _savediary = async (text) => {
  try {
    await AsyncStorage.setItem(dateString + "diary", text);
  } catch(error) {
    console.error(error);
  }
};

3. 优化dateString生成逻辑

当前用for in循环遍历day对象,最终dateString只会是对象的最后一个属性值,不符合预期。如果day是包含日期的结构化对象,建议明确取值:

// 示例:假设day包含date属性,根据实际结构调整
const dateString = day.date;
// 若需要组合多属性:
// const dateString = `${day.year}-${day.month}-${day.day}`;

4. 修复拼写错误

导入语句中的Compomen是拼写错误,直接删除即可(未被使用):

import React, {useState, useEffect} from 'react';

5. 移除冗余的SafeAreaProvider

SafeAreaProvider只需在App根组件中使用一次,无需在每个页面嵌套,建议移除当前组件中的该标签。

修复后的完整代码示例

import React, {useState, useEffect} from 'react';
import {View, TextInput, StyleSheet, Text, TouchableOpacity, Image} from 'react-native';
import AsyncStorage from "@react-native-async-storage/async-storage";

function DetailScreen({ navigation, route }) {
  const { day } = route.params;
  const [title, setTitle] = useState("");

  // 根据day实际结构调整dateString的生成方式
  const dateString = day.date;

  const handleChangeTitle = (text) => {
    setTitle(text);
    _savediary(text);
  }

  const _readdiary = async () => {
    try {
      const savedText = await AsyncStorage.getItem(dateString + "diary");
      if (savedText == null) {
        setTitle("Write your day here.");
      } else {
        setTitle(savedText);
      }
    } catch(error) {
      console.error(error);
    }
  };

  const _savediary = async (text) => {
    try {
      await AsyncStorage.setItem(dateString + "diary", text);
    } catch(error) {
      console.error(error);
    }
  };

  useEffect(() => {
    _readdiary();
  }, [dateString]);

  return(
    <View style={{flexDirection: 'column'}}>
      <View style={{flexDirection: 'row'}}>
        <Text style={styles.date}> {dateString}</Text>
        <TouchableOpacity activeOpacity={0.5} onPress={() => navigation.push('Mood', {day})}>
          <Image 
             source={require('./assets/select.png')}
             style={styles.sticker}
          />
        </TouchableOpacity>
      </View>
      <TextInput
          style={{padding: 10}}
          onChangeText={handleChangeTitle}
          editable
          multiline
          value={title}
        />
    </View>
  );
}

const styles = StyleSheet.create({
  input_container: {
    borderWidth: 0.5,
    padding: 15,
    fontSize: 16,
    marginTop: 20,
    borderRadius: 50,
  },
  date: {
    fontSize: 30,
    width: "75%"
  },
  sticker: {
    height: 50,
    width: 50,
  },
  center: {
    flex: 1,
    alignItems: "center"
},
});

export default DetailScreen;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 12:59:14