Untitled
unknown
javascript
4 years ago
3.3 kB
13
Indexable
/**
* Здравствуйте!
*
* Найдите пожалуйста ошибки коде,
* а также, по возможности, оптимизируйте время рендера (не трогая ExpensiveTree).
*
* Пришлите ссылку с исправленным кодом (Gist, CodeSandbox, CodePen, JSBin, PasteBin, etc)
*/
import React, { useEffect, useState } from "react";
type Props = {
todos?: TodoItem[];
};
type TodoItem = {
id: string | number;
title: string;
isDone?: boolean;
};
const App: React.FC<Props> = props => {
const [todos, setTodos] = useState<TodoItem[]>(props.todos || []);
const [filter, setFilter] = useState<"all" | "undone">("all");
const [doneCount, setDoneCount] = useState(0);
useEffect(() => {
if (props.todos?.length) {
setFilter("all");
}
}, [props.todos]);
const addTodo = (title?: string) => {
if (!title) {
title = prompt("What to do?") || undefined;
}
if (title) {
setTodos(
todos.concat({
id: +Date.now(),
title
})
);
}
};
const markAsDone = (todo: TodoItem) => {
const index = todos.findIndex(item => item.id === todo.id);
if (index >= 0) {
const newTodos = [...todos];
newTodos.splice(index, 1, { ...todo, isDone: true });
setTodos(newTodos);
}
setDoneCount(doneCount + 1);
};
const markAsUndone = (todo: TodoItem) => {
const index = todos.findIndex(item => item.id === todo.id);
if (index >= 0) {
const newTodos = [...todos];
newTodos.splice(index, 1, { ...todo, isDone: false });
setTodos(newTodos);
}
setDoneCount(doneCount - 1);
};
const deleteTodo = (todo: TodoItem) => {
const index = todos.findIndex(item => item.id === todo.id);
if (index >= 0) {
const newTodos = [...todos];
newTodos.splice(index, 1);
setTodos(newTodos);
}
if (todo.isDone) {
setDoneCount(doneCount - 1);
}
};
const onFilterButtonClick = () => {
setFilter(filter === "all" ? "undone" : "all");
};
return (
<div>
<p>{`${doneCount} / ${todos.length}`}</p>
<ul>
{todos
.filter(todo => (filter === "undone" ? !todo.isDone : true))
.map(todo => (
<li key={`${todo.id}`}>
<p>{`${todo.isDone ? "✅ " : ""}${todo.title}`}</p>
<button
onClick={() => {
todo.isDone ? markAsUndone(todo) : markAsDone(todo);
}}
>
{todo.isDone ? "Undone" : "Done"}
</button>
<button onClick={() => deleteTodo(todo)}>{"Delete"}</button>
</li>
))}
</ul>
<button onClick={() => addTodo()}>{"Add"}</button>
<button onClick={() => onFilterButtonClick()}>
{`Show ${filter === "all" ? "undone" : "all"} todos`}
</button>
<ExpensiveTree />
</div>
);
};
function ExpensiveTree() {
const now = performance.now();
while (performance.now() - now < 1000) {
// Artificial delay -- do nothing for 1000ms
}
return null;
}
export default App;
Editor is loading...