Goal: I am trying to persist data using local storage with React.
Approach: Here's my approach to using local storage to store data. First, I have the first useEffect that triggers a localStorage to store an array of items, which are checkboxes. This happens every time a user adds a new toDo checkbox. Secondly, I have another useEffect that listens to the current location of the page. Whenever a user navigates to another page and comes back to the current page, useEffect will trigger the localStorage.get('tasks') and store the objects in the array to the hook called setToDo. This will render items that were stored previously with local storage.
Problem: The problem I keep getting is Objects are not valid as React child even though I tried appending all the objects in the array from localStorage.get('tasks') to the "toDo" hook by using array destructing. Ex. setToDo(prevItems=> [...prevItems, ...value] within the second useEffect. This should be able to render the list of objects in the array using the map function as displayed in the code. Also, items in localStorage are being stored because I checked it with Chrome. Please help me because I've been struggling a lot and have tried every solution(s) possible, yet no results.
Image of error message https://i.sstatic.net/cMuPi.jpg Quick Note: The item_value shown in the image holds a component called PriorityLists, which renders a checkbox with textarea as shown here-> https://i.sstatic.net/p057C.jpg
Code This code should suffice to solve the problem.
import React, { useState, useEffect } from 'react';
import { Delete, Refresh, Add } from '../components/Actions';
import { Header } from '../components/Header';
import { PriorityLists } from '../components/PriorityLists';
import { v4 as uuidv4 } from 'uuid';
function Task() {
const [toDo, setToDo] = useState([]);
const [idsToRefresh, setIdsToRefresh] = useState([]);
const [filter_items, setFilterItems] = useState(false);
const [ids, setIds] = useState([]);
const [currentPath, setCurrentPath] = useState(window.location.pathname);
useEffect(() => {
if (toDo[0] !== undefined) {
localStorage.setItem('tasks', JSON.stringify(toDo));
}
}, [toDo]);
useEffect(() => {
const { pathname } = window.location;
console.log('path');
setCurrentPath(pathname);
if (JSON.parse(localStorage.getItem('tasks'))) {
const value = JSON.parse(localStorage.getItem('tasks'));
setToDo((prevItems) => [...prevItems, ...value]);
console.log(value);
}
}, [window.location.pathname]);
useEffect(() => {
if (toDo[0] !== undefined) {
setToDo(
toDo.filter((item) => {
return !ids.includes(item._Id);
})
);
}
}, [filter_items]);
function addIds(checked, id_to_be_deleted) {
if (!checked) {
setIds((item) => [...item, id_to_be_deleted]);
} else {
setIds(
ids.filter((item) => {
return item !== id_to_be_deleted;
})
);
}
}
function addToDos() {
const id = uuidv4();
setToDo(
toDo.concat({
_Id: id,
item_value: <PriorityLists id={id} checked={false} addIds={addIds} />,
})
);
setIdsToRefresh(idsToRefresh.concat(id));
}
function refresh() {
setToDo(
toDo.filter((item) => {
return !idsToRefresh.includes(item._Id);
})
);
}
return (
<div className="main-content">
<div className="container-fluid">
<div className="row underline">
<div className="col">
<div className="row">
<div className="col-3 pt-2">
<Refresh _refresh={refresh} />
</div>
<div className="col-6 text-center">
<Header header={'Tasks'} />
</div>
<div className="col-3 pt-2">
<button className="float-right">
<Delete
setFilterItems={setFilterItems}
filter={filter_items}
/>
</button>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col">
{toDo.map((item) => {
return (
<div key={item._Id}>
<ul>
<li>{item.item_value}</li>
</ul>
</div>
);
})}
</div>
</div>
<div className="row">
<div className="col pr-4">
<Add addToDos={addToDos} />
</div>
</div>
</div>
</div>
);
}
export default Task;