import { useEffect, useState } from "react";

В коде не очищается interval, мутируется state и используется нестабильный key; запросы также могут перезаписывать более свежие данные.

Короткий ответ

Что ответить на собеседовании

В коде не очищается interval, мутируется state и используется нестабильный key; запросы также могут перезаписывать более свежие данные.

Подробный разбор

Ответ с пояснениями

Условие

import { useEffect, useState } from "react";

export const TaskList = ({ api, filter }) => { const [tasks, setTasks] = useState([]); const [newTitle, setNewTitle] = useState("");

useEffect(() => { api.getTasks(filter).then((res) => setTasks(res)); const interval = setInterval(() => { api.getTasks(filter).then((res) => setTasks(res)); }, 3000); }, [filter, api]);

const addTask = () => { tasks.push({ id: Date.now(), title: newTitle, status: "active" }); setTasks(tasks); setNewTitle(""); };

return ( <div style={{ padding: 10 }}> <input value={newTitle} onChange={(e) => setNewTitle(e.target.value)} /> <button onClick={addTask}>Add Task Active: {tasks.filter((t) => t.status === "active").length} {tasks.map((task) => ( <li key={task.title} style={{ color: task.status === "done" ? "gray" : "black" }} > {task.title} ))} ); };

Ответ

В коде не очищается interval, мутируется state и используется нестабильный key; запросы также могут перезаписывать более свежие данные.

Возвращайте cleanup эффекта, отменяйте либо игнорируйте устаревшие ответы и обрабатывайте ошибки. Для локального добавления используйте setTasks(prev => [...prev, newTask]), а ключом — task.id. Date.now не гарантирует уникальность ID. Периодический серверный ответ сотрёт несохранённую локальную задачу: нужен create API или отдельный согласованный слой optimistic-изменений. Рекурсивный timeout после завершения запроса убирает перекрытие polling-запросов.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее