我正在使用下面的代码创建一个简单的待办事项列表.除了异步存储组件之外,其他一切都正常工作,因为任务要么没有保存,要么没有提取.有谁能指出我可以对useEffect做些什么修改来解决这个问题吗?

/* eslint-disable prettier/prettier */
import React, {useState, useEffect} from 'react';
import {View, StyleSheet, FlatList, Alert} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import uuid from 'react-native-uuid';
import Header from './components/header.js';
import Task from './components/task.js';
import Add from './components/add.js';

const App = () => {
const [tasks, setTasks] = useState([]);

const addTask = (text) => {
  if (!text) {
    Alert.alert(null,'No task entered\nPlease enter a task',);
  } else {
    setTasks(prevState => {
      return [...prevState, {id: uuid.v4(), title: text}];
    });
  }
};

const removeTask = (id) => {
  setTasks(prevState =>{
      return prevState.filter(task => task.id!=id);
  }); 
};

useEffect(() => {
 const saveTasks = async () => {
    await AsyncStorage.setItem('TASKS', JSON.stringify(tasks));
  }
  saveTasks();
}, [tasks]);

useEffect(() => {
  const fetchTasks = async () =>{
    const saved = await AsyncStorage.getItem('TASKS');
    setTasks(JSON.parse(saved));
  }
  fetchTasks();
}, []);

 return (
    <View style={styles.container}>
      <Header/>
      <Add addTask={addTask} />
      <FlatList
        data={tasks}
        renderItem={({ item }) => <Task text={item.title} removeTask={removeTask} id={item.id}/>}
        keyExtractor={task => task.id}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default App;

推荐答案

Problem

该问题是由低于useEffect引起的.每次tasks发生变化时,它都会将tasks保存在存储器中,而且在第一次渲染时,tasks等于[],即给定给useState的值.

useEffect(() => {
 const saveTasks = async () => {
    await AsyncStorage.setItem('TASKS', JSON.stringify(tasks));
  }
  saveTasks();
}, [tasks]);

Solution

解决此问题的一个简单方法是删除上述useEffect,并将addTaskremoveTask更改如下:

const addTask = (text) => {
  if (!text) {
    Alert.alert(null,'No task entered\nPlease enter a task',);
  } else {
    const newTasks = [...tasks, {id: uuid.v4(), title: text}];
    await AsyncStorage.setItem('TASKS', JSON.stringify(newTasks));
    setTasks(newTasks);
  }
};
const removeTask = (id) => { 
  const newTasks = tasks.filter(task => task.id!=id);
  await AsyncStorage.setItem('TASKS', JSON.stringify(newTasks));
  setTasks(newTasks); 
};

Javascript相关问答推荐

reaction如何在不使用符号的情况下允许多行返回?

React对话框模式在用户单击预期按钮之前出现

了解Node.js中的EventEums和浏览器中的addEventEums之间的关系

配置WebAssembly/Emscripten本地生成问题

jQuery s data()[storage object]在vanilla JavaScript中?'

屏幕右侧屏障上的产卵点""

在Three JS中看不到补间不透明度更改效果

如果Arrow函数返回函数,而不是为useEffect返回NULL,则会出现错误

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

当id匹配时对属性值求和并使用JavaScript返回结果

JQuery Click事件不适用于动态创建的按钮

第三方包不需要NODE_MODULES文件夹就可以工作吗?

邮箱密码重置链接不适用于已部署的React应用程序

Phaserjs-创建带有层纹理的精灵层以自定义外观

更新Redux存储中的对象数组

try 将Redux工具包与MUI ToggleButtonGroup组件一起使用时出错

图表4-堆叠线和条形图之间的填充区域

Reaction即使在重新呈现后也会在方法内部保留局部值

使用可配置项目创建网格

TabNavigator和StackNavigator之间的Reaction Native中的导航问题