example

 avatar
unknown
jsx
3 years ago
2.7 kB
5
Indexable
import React, { useState } from 'react'

interface Props {
  todos: TodoItem[]
}

interface 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<number>(0)

//   useEffect(() => {
//           if (props.todos.length) {
//       setFilter('all');
//     }
//   })

  const addTodo = (title?: string | null) => {
    const entities = [...todos]
    if (!title) title = prompt('What to do?')
    if (title) {
      entities.push({
        id: +Date.now(),
        title,
      })
    }
    setTodos(entities)
  }

  const markAsDone = (todo: TodoItem) => {
    const entities = [...todos]
    const index = entities.findIndex((item) => item.id === todo.id)

    if (index >= 0) {
      entities.splice(index, 1, { ...todo, isDone: false })

      setTodos(entities)
    }
    setDoneCount(prev => prev - 1)
  }

  const markAsUndone = (todo: TodoItem) => {
    const entities = [...todos]
    const index = entities.findIndex((item) => item.id === todo.id)

    if (index >= 0) {
      entities.splice(index, 1, { ...todo, isDone: true })
      setTodos(entities)
    }

    setDoneCount((prev) => prev + 1)
  }
  const deleteTodo = (todo: TodoItem) => {
    const entities = [...todos]
    const index = entities.findIndex((item) => item.id === todo.id)
    if (index >= 0) {
      entities.splice(index, 1)
      setTodos(entities)
    }
  }

  const onFilterButtonClick = () => {
    setFilter(filter === 'all' ? 'undone' : 'all')
  }

  return (
    <div>
      <p>{`${doneCount} / ${todos.length}`}</p>
      <ul>
        {todos
          .filter((todo) => (filter === 'undone' ? !todo.isDone : todo.isDone))
          .map((todo) => (
            <div key={`${todo.id}`}>
              <p>{`${todo.isDone ? '✅ ' : ''}${todo.title}`}</p>
              <button
                onClick={() => {
                  todo.isDone ? markAsDone(todo) : markAsUndone(todo)
                }}
              >
                {'Done'}
              </button>
              <button onClick={() => deleteTodo(todo)}>{'Delete'}</button>
            </div>
          ))}
      </ul>
      <button onClick={() => addTodo()}>{'Add'}</button>
      <button onClick={() => onFilterButtonClick()}>
        {`Show ${filter === 'all' ? 'undone' : 'all'} todos`}
      </button>
      <ExpensiveTree />
    </div>
  )
}

function ExpensiveTree() {
  let now = performance.now()

  while (performance.now() - now < 1000) {
    // Artificial delay -- do nothing for 1000ms
  }

  return null
}

export default App
Editor is loading...