'localStorage.getItem() doesn't retrieve data on page refresh - ReactJs (TypeScript)

I'm trying to create a to-do list app with ReactJs, working with localStorage the setItem() works fine but the getItem() doesn't return anything except empty array!

  • I'm using || "" because the JSON.parse() returns string || null in TypeScript.
useEffect(() => {
   localStorage.setItem("todos", JSON.stringify(todos));
 }, [todos]);

 useEffect(() => {
   const items = JSON.parse(localStorage.getItem("todos") || "");
   if (items) {
     setTodos(items);
   }
 }, []);

Here's where i supply data to todos

const [todos, setTodos] = useState<todosObj[]>([]);
const [count, setCount] = useState(1);
const [status, setStatus] = useState<"All" | "completed" | "uncompleted">(
    "All"
  );
const [inputText, setInputText] = useState("");
const [date, setDate] = useState(new Date());

const inputHandler = (e: React.FormEvent<HTMLInputElement>) => {
    setInputText(e.currentTarget.value);
  };

const submitHandler = (e: React.FormEvent<HTMLButtonElement>) => {
    e.preventDefault();
    setCount(count + 1);

    if (inputText !== "") {
      setTodos([
        ...todos,
        {
          id: count,
          text: inputText,
          completed: false,
          date: date,
        },
      ]);
    }

    setInputText("");
  };


Solution 1:[1]

Sorry, I dont have enough reputation to comment, so have to post it as an answer:

Is the initial data for todos set? It is better if you can provide where you supply data to todos

Solution 2:[2]

I Fixed the problem by initializing the todos state by getItem()
like this :

const [todos, setTodos] = useState<todosObj[]>(
    JSON.parse(localStorage.getItem("todos") || "") || []
  );

If someone knows the reason why it wasn't working please tell me.

Solution 3:[3]

useEffect(() => {
   const stringifyTodos = JSON.stringify(todos)
   localStorage.setItem("todos", stringifyTodos);
 }, [todos]);

 useEffect(() => {
   const storedTodos = localStorage.getItem("todos")
   const items = JSON.parse(storedTodos);
   if (items) {
     setTodos(items);
   }
 }, []);

Try this way I think it will work.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Gabsys
Solution 2 Mohammed Azzab
Solution 3