2

I am using the below code to create a simple to-do list. Everything works fine except the async-storage components since the tasks are either not being saved or not being fetched. Could anyone kindly point out any modifications I can do to the useEffects to fix this issue?

/* 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;
1

1 Answer 1

2

Problem

The problem is caused by the below useEffect. It saves tasks in storage every time tasks changes, but also on first render where tasks is equal to [], the value given to useState.

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

Solution

An easy way to solve this issue is to remove the above useEffect, and change addTask and removeTask as follow:

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); 
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.