Назад к вопросам
СБЕР
Middle+
3
Посмотри на код React-приложения (Todo-список) и исправь проблемы: обработка запроса к API, работа с состоянием, обработка ошибок, добавление новых задач, отметка задач как выполненных.
Компании, где спрашивали
Ответ от нейросети
sobes.tech AI
В React-приложении Todo-списка часто встречаются следующие проблемы и способы их решения:
-
Обработка запроса к API
- Используйте
useEffectдля загрузки данных при монтировании компонента. - Обрабатывайте ошибки с помощью
try/catchили.catch. - Показывайте индикатор загрузки и сообщения об ошибках.
- Используйте
-
Работа с состоянием
- Используйте
useStateдля хранения списка задач. - При обновлении списка задач используйте функциональный сеттер, чтобы избежать проблем с асинхронностью.
- Используйте
-
Обработка ошибок
- Локально храните состояние ошибки.
- Показывайте пользователю понятное сообщение.
-
Добавление новых задач
- При добавлении новой задачи обновляйте состояние, добавляя новую задачу в массив.
- Можно оптимистично обновлять UI, а затем синхронизировать с сервером.
-
Отметка задач как выполненных
- Обновляйте состояние задачи, меняя поле
completed. - При необходимости отправляйте обновление на сервер.
- Обновляйте состояние задачи, меняя поле
Пример исправленного кода:
import React, { useState, useEffect } from 'react';
function TodoList() {
const [todos, setTodos] = useState([]);
const [newTask, setNewTask] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchTodos() {
setLoading(true);
setError(null);
try {
const response = await fetch('/api/todos');
if (!response.ok) throw new Error('Ошибка загрузки задач');
const data = await response.json();
setTodos(data);
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
}
fetchTodos();
}, []);
const addTask = async () => {
if (!newTask.trim()) return;
const task = { id: Date.now(), text: newTask.trim(), completed: false };
setTodos(prev => [...prev, task]);
setNewTask('');
try {
const response = await fetch('/api/todos', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(task),
});
if (!response.ok) throw new Error('Ошибка добавления задачи');
} catch (e) {
setError(e.message);
// Можно откатить добавление задачи или уведомить пользователя
}
};
const toggleCompleted = async (id) => {
setTodos(prev => prev.map(todo => todo.id === id ? { ...todo, completed: !todo.completed } : todo));
try {
const todo = todos.find(t => t.id === id);
const response = await fetch(`/api/todos/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ completed: !todo.completed }),
});
if (!response.ok) throw new Error('Ошибка обновления задачи');
} catch (e) {
setError(e.message);
// Можно откатить изменение или уведомить пользователя
}
};
if (loading) return <p>Загрузка...</p>;
if (error) return <p style={{ color: 'red' }}>{error}</p>;
return (
<div>
<input
value={newTask}
onChange={e => setNewTask(e.target.value)}
placeholder="Новая задача"
/>
<button onClick={addTask}>Добавить</button>
<ul>
{todos.map(todo => (
<li key={todo.id} onClick={() => toggleCompleted(todo.id)}
style={{ textDecoration: todo.completed ? 'line-through' : 'none', cursor: 'pointer' }}>
{todo.text}
</li>
))}
</ul>
</div>
);
}
export default TodoList;