react native with zustand persist

Viewed 519

I'm trying to implement a simple todo app with react-native and zustand persist, the code without the persist method is working fine, but when I try to introduce persist, I run into errors or I'm not able to correctly implement it, I went through the documentation on zustand page, but it is not working. Below is the relevant code and errors:

App.tsx

const App = () => {
  const { todos, addTodo, getTodos } = useTodoStore((state: TodoState) => state);
  
  useEffect(() => {
    getTodos();
  }, []);

  return (
    ...
  )
}

zustand store:

import create from 'zustand';
import { persist } from 'zustand/middleware';
import AsynStorage from '@react-native-async-storage/async-storage';

export interface Todo {
  id: string;
  text: string;
  completed: boolean;
  createdAt: string;
}

export interface TodoState {
  todos: Todo[];
  addTodo: (todo: Todo) => void;
  getTodos: () => void;
  removeTodo: (id: string) => void;
  toggleTodo: (id: string) => void;
}

export const useTodoStore = create<TodoState>(
  // @ts-ignore
  persist(
    set => ({
      todos: [],
      getTodos: () => {
        AsynStorage.getItem('todo-storage').then(todos => {
          if (todos) {
            set(state => ({ ...state, todos: JSON.parse(todos) }));
          }
        });
      },
      addTodo: (todo: Todo) => {
      set(state => {
        console.log('state: ', state.todos);
        return {
          ...state,
          todos: [...state.todos, todo],
          };
        });
      },
      removeTodo: (id: string) => {
        set(state => ({
          ...state,
          todos: state.todos.filter(todo => todo.id !== id),
        }));
      },
      toggleTodo: (id: string) => {
        set(state => ({
          ...state,
          todos: state.todos.map(todo =>
            todo.id === id ? { ...todo, completed: !todo.completed } : todo,
          ),
        }));
      },
    }),
    {
      name: 'todo-storage',
      getStorage: () => AsynStorage,  
    },
  ),
);

Now, when I try to add a todo, I run into the following error:

ERROR  TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.

So, does anyone have a code example with persist (react-native), I don't understand what I'm doing wrong here, I'm doing as shown in docs.

EDIT: If I remove persist middleware and all code related to it, it works just fine, also, to note:

When I use persist middleware with async-storage, the state is this:

LOG  state:  {"state": {"_hasHydrated": true, "todos": {"state": [Object], "version": 0}}, "version": 0}

And when I don't use persist it works:

LOG  state:  [{"completed": false, "createdAt": "Fri Jul 22 2022 14:27:47 GMT+0530 (IST)", "id": "6bfdab5e34b198", "text": "Let’s seeeee"}]
1 Answers
Related