Home  >  Q&A  >  body text

Reorder array in state

I use zustand to create a global state with an array of to-do items, and I have functionality to add, remove, and toggle completion/undo for each to-do item.

I also use Dnd Kit to drag and drop each ToDo component and reorder them in the global context, for which I need to create a reorderTodo function in the zustand store this way:

const handleDragEnd = (event: any) => {
    const { active, over } = event;

    if (active.id !== over.id) {
        const newIndex = filteredTodos.findIndex(
            (todo) => todo.id === over.id
        );
        setFilteredTodos((filteredTodos) => {
            const oldIndex = filteredTodos.findIndex(
                (todo) => todo.id === active.id
            );

            return arrayMove(filteredTodos, oldIndex, newIndex);
        });

        reorderTodo(active.id, newIndex);
    }
};


import { create } from "zustand";

export const useTodosStore = create(() => ({
    todos: [
        { id: 1, text: "Learn TypeScript", done: true },
        { id: 2, text: "Try immer", done: false },
        { id: 3, text: "Tweet about it", done: false },
    ],
    addTodo: (text: string, done: boolean) => {
        useTodosStore.setState((state) => ({
            todos: [
                ...state.todos,
                { id: state.todos.length + 1, text, done: done },
            ],
        }));
    },
    toggleTodo: (id: number) =>
        useTodosStore.setState((state) => ({
            todos: state.todos.map((todo) =>
                todo.id === id ? { ...todo, done: !todo.done } : todo
            ),
        })),
    removeTodo: (id: number) =>
        useTodosStore.setState((state) => ({
            todos: state.todos.filter((todo) => todo.id !== id),
        })),

    reorderTodo: (id: number, position: number) =>
        useTodosStore.setState((state) => {
            const todos = [...state.todos];
            const todo = todos.find((todo) => todo.id === id);
            if (!todo) return;
            const idx = todos.indexOf(todo);
            todos.splice(idx, 1);
            todos.splice(position, 0, todo);
            return { todos };
        }),
}));

It gave me a big typescript error in VSCode:

Argument of type '(state: { todos: { id: number; text: string; done: boolean; }[]; addTodo: (text: string, done: boolean) => void; toggleTodo: (id: number) => void; removeTodo: (id: number) => void; reorderTodo: (id: number, position: number) => void; }) => { ...; } | undefined' is not assignable to parameter of type '{ todos: { id: number; text: string; done: boolean; }[]; addTodo: (text: string, done: boolean) => void; toggleTodo: (id: number) => void; removeTodo: (id: number) => void; reorderTodo: (id: number, position: number) => void; } | Partial<...> | ((state: { ...; }) => { ...; } | Partial<...>)'.
  Type '(state: { todos: { id: number; text: string; done: boolean; }[]; addTodo: (text: string, done: boolean) => void; toggleTodo: (id: number) => void; removeTodo: (id: number) => void; reorderTodo: (id: number, position: number) => void; }) => { ...; } | undefined' is not assignable to type '(state: { todos: { id: number; text: string; done: boolean; }[]; addTodo: (text: string, done: boolean) => void; toggleTodo: (id: number) => void; removeTodo: (id: number) => void; reorderTodo: (id: number, position: number) => void; }) => { ...; } | Partial<...>'.

But I can run the application in development mode using yarn dev and the problem arises when I want to build the application using yarn build it gives in console got me this error and therefore I was unable to deploy the application in Netlify/vercel

How can I create a reordering function to fix this error?

P粉741678385P粉741678385225 days ago337

reply all(1)I'll reply

  • P粉432930081

    P粉4329300812024-03-31 10:10:35

    The problem is that the set method requires a return state, and your code returns undefined in setState: if (!todo) return;. In this line you can change the code to if (!todo) return { todos };

    reply
    0
  • Cancelreply