menu
search
...

todo list using react

eye-

When i changed jobs for the second time, the interviewer asked me to create a todo list using react. I think it's a good question to test the candidate's ability to think and code. Not like stereotyped writing, it's more like a real interview question.

Let's start with the basic structure of the todo list.

First, we need a input field to add a new todo.

<input type="text" placeholder="new thing to be done" />

Second, we need a list to show all the todos.

const [todos, setTodos] = useState([])

then we need to render the list:

{
  todos.map((todo) => <li key={todo.id}>{todo.text}</li>)
}

Now, let's put these components together.

const [todos, setTodos] = useState([])

return (
  <div>
    <input type="text" placeholder="new thing to be done" />
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  </div>
)

Now, we need to handle the input field. We can use form to wrap the input field.

const inputRef = useRef(null)

<form onSubmit={handleSubmit}>
  <input type="text" placeholder="new thing to be done" ref={inputRef} />
</form

Why we need to use form? Because we want to prevent the page from refreshing when we enter a new todo. For sure, you can also choose other ways to handle this.

const handleSubmit = (e) => {
  e.preventDefault()
  setTodos([...todos, { id: Date.now(), label: inputRef.current.value }])
  inputRef.current.value = ""
}

Let's put these components together.

function TodoList() {
  const inputRef = useRef(null)
  const [todos, setTodos] = useState([])

  const handleSubmit = (e) => {
    e.preventDefault()
    setTodos([...todos, { id: Date.now(), label: inputRef.current.value }])
    inputRef.current.value = ""
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" placeholder="new thing to be done" ref={inputRef} />
      </form>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>{todo.label}</li>
        ))}
      </ul>
    </div>
  )
}

Now we can add a new todo. But we need to toggle the todo when it's done or not. We should add a checkbox to the todo. And add a line-through style if it's checked.

const handleToggle = (id) => {
  setTodos(
    todos.map((todo) => (todo.id === id ? { ...todo, done: !todo.done } : todo))
  )
}

<li key={todo.id}>
    <input
        type="checkbox"
        checked={todo.done}
        onChange={() => handleToggle(todo.id)}
    />
    <label className={item.done ? "done" : "undo"}>{todo.label}</label>
</li>

After we also need to add a button to delete the todo.

<li key={todo.id}>
  <input
    type="checkbox"
    checked={todo.done}
    onChange={() => handleToggle(todo.id)}
  />
  {todo.label}
  <button onClick={() => handleDelete(todo.id)}>x</button>
</li>
const handleDelete = (id) => {
  setTodos(todos.filter((todo) => todo.id !== id))
}

That's it. We have a todo list.

function TodoList() {
  const inputRef = useRef(null)
  const [todos, setTodos] = useState([])

  const handleSubmit = (e) => {
    e.preventDefault()
    setTodos([
      ...todos,
      { id: Date.now(), label: inputRef.current.value, done: false },
    ])
    inputRef.current.value = ""
  }

  const handleDelete = (id) => {
    setTodos(todos.filter((todo) => todo.id !== id))
  }

  const handleToggle = (id) => {
    setTodos(
      todos.map((todo) =>
        todo.id === id ? { ...todo, done: !todo.done } : todo
      )
    )
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" placeholder="new thing to be done" ref={inputRef} />
      </form>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <input
              type="checkbox"
              checked={todo.done}
              onChange={() => handleToggle(todo.id)}
            />
            <label className={item.done ? "done" : "undo"}>{todo.label}</label>
            <button onClick={() => handleDelete(todo.id)}>x</button>
          </li>
        ))}
      </ul>
    </div>
  )
}

If you can complete this above, i think your answer basically meets the requirements.

But we can do better, like:

If you can complete these above, i think your answer is excellent. Have a try, good luck!

some useful git commands