How to Update a Kanban List Dynamically After Creating a New Task with MongoDB?

‘m working on a Kanban application where I need the list of tasks to update immediately after creating a new task. I’m using MongoDB with Express and Axios, but I’m having trouble getting the list to refresh dynamically without a full page reload.

Here are the main components of my application:

1.List Component: This component fetches and displays tasks grouped by stages. It uses the useState and useEffect hooks to manage state and fetch data from the server.

type Task = {
  id: string;
  title: string;
  description: string;
  dueDate?: Date;
  completed: boolean;
  stageId?: string | null;
  users: { id: string; name: string; avatarUrl: string }[];
  createdAt: string;
  updatedAt: string;
};

type TaskStage = {
  id: string;
  title: string;
  tasks: Task[];
  createdAt: string;
  updatedAt: string;
};

const List = ({ children }: React.PropsWithChildren) => {
  const [tasks, setTasks] = useState<Task[]>([]);
  const [stages, setStages] = useState<TaskStage[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const {replace} = useNavigation();

  // Fetch tasks and stages from MongoDB
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get('http://localhost:3000/');
        setTasks(response.data.tasks);
        setStages(response.data.taskStages);
      } catch (error) {
        console.error('Error fetching data:', error);
      } finally {
        setIsLoading(false);
      }
    };
    fetchData();
  }, []);
  // console.log(tasks);
  // console.log(stages);
 
  // Group tasks by stages
  const tasksStages = React.useMemo(() => {
    if (!tasks.length || !stages.length) {
      return {
        unassignedStage: [],
        columns: []
      };
    }

    const unassignedStage = tasks.filter((task: Task) => !task.stageId) ?? [];
    const groupedStages = stages.map((stage: TaskStage) => ({
      ...stage,
      tasks: tasks.filter((task: Task) => task.stageId === stage.id) ?? [],
    })) ?? [];

    return {
      unassignedStage,
      columns: groupedStages
    };
  }, [stages, tasks]);
  
  const handleTaskCreate = (newTask: Task) => {
    setTasks((prevTasks) => [...prevTasks, newTask]);
};
  // Handle adding new card by pressing the pluss icon : 
  const handleAddCard = (args: { stageId: string }) => {
    const path = args.stageId === 'unassigned' ? '/tasks/new' : `/tasks/new?stageId=${args.stageId}`;
    replace(path); // Use navigate instead of replace
  };
...
 return (
    <>
      <KanbanBoardContainer>
        <KanbanBoard onDragEnd={handleOnDragEnd}>
          <KanbanColumn
            id="unassigned"
            title="Unassigned"
            count={tasksStages.unassignedStage.length || 0}
            onAddClick={() => handleAddCard({ stageId: 'unassigned' })} description={undefined}>
            {tasksStages.unassignedStage.map((task: Task) => (
              <KanbanItem key={task.id} id={task.id} data={{ ...task, stageId: 'unassigned' }}>
                <ProjectCardMemo {...task} dueDate={String(task.dueDate) || undefined} />
              </KanbanItem>
            ))}
            {!tasksStages.unassignedStage.length && <KanbanAddCardButton onClick={() => handleAddCard({ stageId: 'unassigned' })} />}
          </KanbanColumn>

          {tasksStages.columns?.map((column: TaskStage) => (
            <KanbanColumn
              key={column.id}
              id={column.id}
              title={column.title}
              count={column.tasks.length}
              onAddClick={() => handleAddCard({ stageId: column.id })} description={undefined}>
              {column.tasks.map((task: Task) => (
                <KanbanItem key={task.id} id={task.id} data={task}>
                  <ProjectCardMemo {...task} dueDate={String(task.dueDate) || undefined} />
                </KanbanItem>
              ))}
              {!column.tasks.length && <KanbanAddCardButton onClick={() => handleAddCard({ stageId: column.id })} />}
            </KanbanColumn>
          ))}
        </KanbanBoard>
      </KanbanBoardContainer>
      {children}
    </>
  );
};

export default List;

2.TasksCreatePage Component: This component is used to create new tasks. It opens a modal form where users can input task details. Upon submission, the task is created, but I need to find a way to ensure the new task appears in the list immediately.

import { useSearchParams } from "react-router-dom";
import { useModalForm } from "@refinedev/antd";
import { useNavigation } from "@refinedev/core";
import { Form, Input, Modal } from "antd";
import axios from "axios";

const CreateTask = () => {
  const [searchParams] = useSearchParams();
  const { list } = useNavigation();

  const { formProps, modalProps, close } = useModalForm({
    action: "create",
    defaultVisible: true,
  });

  const onSubmit = async (values: any) => {
    const stageId = searchParams.get("stageId") || null;

    try {
      const response = await axios.post('http://localhost:3000/tasks', {
        title: values.title,
        stageId,
        completed: false,
        users: [],
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
      });

      if (response.status === 201) {
        // Optionally show a success message here
        list("tasks", "replace");
      }
    } catch (error) {
      console.error('Error creating task:', error);
    }

    close();
  };

  return (
    <Modal
      {...modalProps}
      onCancel={() => {
        close();
        list("tasks", "replace");
      }}
      title="Add new card"
      width={512}
    >
      <Form {...formProps} layout="vertical" onFinish={onSubmit}>
        <Form.Item label="Title" name="title" rules={[{ required: true }]}>
          <Input />
        </Form.Item>
      </Form>
    </Modal>
  );
};

export default CreateTask;

3.App Component: This component manages routing in the application and includes a route to TasksCreatePage.

 <Route path="/tasks" element={<List>
                          <Outlet/>
                        </List>}>
                          <Route path="new" element={<CreateTask/>}/>
                          <Route path="edit/:id" element={<EditTask/>}/>
                        </Route>

How can I update the List component dynamically when a new task is created using MongoDB?
I would appreciate any guidance or examples on how to achieve this functionality in a React application.