[Solved] TaskBoard: Update a Single Task Without Replacing the Entire taskData Array

1 Answer 17 Views
TaskBoard
Ismoil
Top achievements
Rank 1
Ismoil asked on 09 Jun 2026, 04:33 PM

We are using KendoReact TaskBoard with a backend.

On every TaskBoard change we receive newData and update state using:

setTaskData(newData);

This replaces the entire tasks array and causes all cards to re-render.

Is there a way to update only the affected task (created, updated, moved, or deleted) instead of replacing the whole taskData collection?

Our backend returns only the changed task, and we would like to keep the frontend synchronized without re-rendering the entire TaskBoard.

What is the recommended approach for this scenario?

1 Answer, 1 is accepted

Sort by
0
Vessy
Telerik team
answered on 11 Jun 2026, 03:40 PM

Hello, Ismoil,

Thank you for the detailed question — this is a great scenario to address.

The `onChange` event on the TaskBoard includes more than just the full `event.data` array. Every change event also carries:

  • event.item - the task after the change (or `null` for a delete).
  • event.previousItem - the task before the change (or `null` for a create).
  • event.type - 'task' or 'column', to distinguish what changed.

These fields make it straightforward to apply a surgical update to your state array instead of replacing it wholesale. The approach below handles all four operations — create, edit, move, and delete — using only the affected task's `id`:

    const [taskData, setTaskData] = React.useState<TaskBoardTaskModel[]>(initialTasks);
    const [columnsData, setColumnsData] = React.useState(initialColumns);

    const onChangeHandler = React.useCallback(
        async (event: TaskBoardChangeEvent) => {
            if (event.type === 'column') {
                setColumnsData(event.data as any[]);
                return;
            }

            
            if (!event.previousItem) {
                setTaskData((prev) => [...prev, event.item as TaskBoardTaskModel]);
            } else if (!event.item) {
                const deletedId = (event.previousItem as TaskBoardTaskModel).id;
                setTaskData((prev) => prev.filter((t) => t.id !== deletedId));
            } else {
                const prevId = (event.previousItem as TaskBoardTaskModel).id;
                const updatedTask = event.item as TaskBoardTaskModel;
                setTaskData((prev) =>
                    prev.map((t) => (t.id === prevId ? updatedTask : t))
                );
            }

            // --- Backend sync ---
            // Your backend returns only the changed task — apply it by id
            try {
                const serverTask = await syncWithBackend(event);
                if (serverTask) {
                    setTaskData((prev) =>
                        prev.map((t) => (t.id === serverTask.id ? serverTask : t))
                    );
                }
            } catch {
                // Optional: rollback optimistic update on error
            }
        },
        []
    );

    return (
        <TaskBoard
            columnData={columnsData}
            taskData={taskData}
            priorities={priorities}
            onChange={onChangeHandler}
        />

When a card is dragged to a new position or column, `event.data` reflects the full reordered array, but `event.item` already carries the task's updated `status` (the column it moved to). The map-by-id approach above correctly updates the task's status field. If preserving the exact intra-column card order matters for rendering, consider using `event.data` for drag operations (identifiable because `event.previousItem` has an `index` property) and the map-by-id approach for edits and creates.

I hope the provided information will be helpful for you.

Regards,
Vessy
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tags
TaskBoard
Asked by
Ismoil
Top achievements
Rank 1
Answers by
Vessy
Telerik team
Share this question
or