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

使用AsyncStorage存储待办事项时列表无法加载问题求助

问题原因及修复方案


1. 空数组判断逻辑错误

JavaScript中数组是引用类型,todos === []永远返回false,两个不同的数组实例哪怕内容完全一致,引用地址不同就不会相等。
修改方案:改成判断数组长度:

todos.length === 0

2. 新增待办后未更新本地state

你在addItem方法中仅把新的待办数组存入了AsyncStorage,没有调用setTodos更新组件的本地状态,界面自然不会触发重渲染刷新列表。
修改方案:在调用_storeData前新增更新state的逻辑:

let newTodos = [newTodo, ...todos];
setTodo('');
setTodos(newTodos); // 新增这行
_storeData(JSON.stringify(newTodos));

3. useEffect依赖配置错误引发死循环风险

你当前把todos作为useEffect的依赖,每次todos变化都会触发_retrieveData读存储,读出来又调用setTodos修改todos,会陷入无限循环。实际上只需要组件首次挂载时读一次存储初始化数据即可。
修改方案:把useEffect的依赖改成空数组:

useEffect(() => {
  _retrieveData();
}, []); // 空数组代表仅挂载时执行一次

4. 错误捕获变量名错误

_storeData方法的catch块中,你打印的变量是e,但catch接收的参数名是error,运行时会报变量未定义错误。
修改方案:统一变量名:

catch (error) {
  console.log(error);
}

5. 删除待办未同步到AsyncStorage

deleteTodo方法中仅更新了本地state,没有同步修改AsyncStorage里的数据,下次APP重启后被删除的待办会重新出现。
修改方案:删除后同步更新存储:

const deleteTodo = (idx) => {
  const newTodos = todos.filter((todo, id) => id !== idx);
  setTodos(newTodos);
  _storeData(JSON.stringify(newTodos));
};

完整修正后的代码

export default function App() {
  const [todo, setTodo] = useState('');
  const [todos, setTodos] = useState([]);

  // 仅挂载时读一次存储初始化数据
  useEffect(() => {
    _retrieveData();
  }, []);

  const addItem = (newTodo) => {
    if (newTodo.length === 0) {
      Alert.alert(
        'Enter a String',
        'You have entered a string with 0 characters',
        [{ text: 'Okay', style: 'default' }]
      );
    } else {
      console.log(newTodo);
      let newTodos = [newTodo, ...todos];
      setTodo('');
      setTodos(newTodos); // 新增更新本地状态
      _storeData(JSON.stringify(newTodos));
    }
  };

  const deleteTodo = (idx) => {
    const newTodos = todos.filter((todo, id) => id !== idx);
    setTodos(newTodos);
    _storeData(JSON.stringify(newTodos)); // 同步更新存储
  };

  const _storeData = async (value) => {
    try {
      await AsyncStorage.setItem('TASKS', value);
    } catch (error) {
      // 修正变量名
      console.log(error);
    }
  };

  const _retrieveData = async () => {
    try {
      const value = await AsyncStorage.getItem('TASKS');
      if (value !== null) {
        setTodos(JSON.parse(value));
        console.log(value);
      }
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <TouchableWithoutFeedback
      onPress={() => {
        Keyboard.dismiss();
      }}
    >
      <View style={styles.outerContainer}>
        <Text style={styles.header}>TODO</Text>
        <View style={styles.container}>
          <TextInput
            placeholder='new todo'
            style={styles.input}
            value={todo}
            onChangeText={(text) => {
              setTodo(text);
            }}
          ></TextInput>
          <Button title='Add' onPress={() => addItem(todo)}></Button>
        </View>
        <ScrollView style={styles.scrollView}>
          {/* 修正空数组判断逻辑 */}
          {todos.length === 0 ? (
            <View>
              <Text>Add a todo!</Text>
            </View>
          ) : (
            todos.map((todo, idx) => (
              <View style={styles.todo} key={idx}>
                <Text style={styles.todoText}>{todo}</Text>
                <View style={styles.delete}>
                  <Button
                    color='red'
                    title='Delete'
                    onPress={() => deleteTodo(idx)}
                  ></Button>
                </View>
              </View>
            ))
          )}
        </ScrollView>
      </View>
    </TouchableWithoutFeedback>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:45:11