likes
comments
collection
share

百度面试官 : 写一个ToDoList吧

作者站长头像
站长
· 阅读数 15

前言

事情是这样的,当我辛辛苦苦,准备了半个月的八股文去尝试大厂面试的时候,以为靠着这些八股,手写题,就算面不到,也不至于很尴尬吧~

结果百度一面的时候,面试官一上来就叫我用脚手架自建项目写一个ToDoList。

我内心直接崩溃了😭😭(已经小半年没有写项目了)

所以现在想给自己长个记性,在背题的同时,也不要把一些最基础实战题给忽视了。

也想给jym提个醒,这真的算是很基础的项目实战题,不太熟的也要小心了,不要到时候真碰到了这类题写不出,那真的太掉价了~

所以现在来看这么一个简单的demo吧~

效果图

百度面试官 : 写一个ToDoList吧

  • 实现任务的添加,删除
  • 点击done按钮能够使对应的item变色

创建react项目

npx create-react-app test
cd test
npm start

接下来你会得到这样的一个目录

百度面试官 : 写一个ToDoList吧

实现任务的增加和删除

import React, { useState} from 'react';


function App() {
  const [todos, setTodos] = useState([]);
  const [inputValue, setInputValue] = useState('');

  // 增加任务
  const handleAddTodo = () => {
  // trim()函数去除输入值两端的空格,然后检查是否为空字符串
    if (inputValue.trim() !== '') {
    // 使用展开运算符(...)将现有的待办事项列表(todos)和一个新的待办事项对象({ inputValue })合并成一个新的数组。
      setTodos([...todos, { inputValue}]);
      setInputValue('');
    }
  };
  
  
  // 删除任务
  const handleDeleteTodo = (index) => {
  // 进行一个浅拷贝
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };


  return (
    <div className="App">
      <h1>Todo List</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index}>
            {todo.inputValue}
            <button onClick={() => handleDeleteTodo(index)}>Delete</button>
          </li>
        ))}
      </ul>
      <input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
      <button onClick={handleAddTodo}>Add Todo</button>
      
    </div>
  );
}

export default App;

删除功能的实现

  // 删除任务
  const handleDeleteTodo = (index) => {
  // 进行一个浅拷贝
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };

如果自己不写一遍的话,有些友友们会忽视这个细节 这里我为什么不能写成

setTodos(todos.splice(index,1));

这样一步到位不是更好?

这一步就相当于直接原地修改state了,在react官方文档中有解释 👉 React中文网 (zcopy.site)

并且直接修改state,react不会重新render

这样会导致一个问题,就是比如这次点击旁边的删除按钮时,并不会及时把该item项删除

实现点击变色

这一步到要求是在delet按钮后面增加一个done按钮,点击后实现点击的那一项变色。

步骤

  • 添加done按钮
 <button onClick={() => handleDoneTodo(index)}>Done</button>
  • 创建事件函数handleDoneTodo
 const handleDoneTodo = (index) => {
    const newTodos = [...todos];
    // 将该下标项的isClick属于改为true
    newTodos[index].isClick = true;
    setTodos(newTodos);
  }

注意,这里的前提是要为原来的todos增加一个isClick属性,这该如何添加呢?

// 在添加函数里
  const handleAddTodo = () => {
    if (inputValue.trim() !== '') {
      setTodos([...todos, { inputValue, isClick: false }]);
      setInputValue('');
    }
  };

setTodos约定了todos要创建为什么样,这里通过对象字面量创建了一个对象,并直接可以增添isClick属性

  • 动态添加样式
      <ul>
        {todos.map((todo, index) => (
          <li key={index} style={{ color: todo.isClick ? 'red' : 'black' }}>
            {todo.inputValue}
            <button onClick={() => handleDeleteTodo(index)}>Delete</button>
            <button onClick={() => handleDoneTodo(index)}>Done</button>
          </li>
        ))}
      </ul>

直接使用style+三目运算符做动态样式的处理

这里还想在介绍一下style和className的区别

  • style 属性用于内联样式,可以直接将样式对象应用于元素。
  • className 属性用于添加 CSS 类名,可以通过类名引用预定义的样式规则。

完整代码

import React, { useState } from 'react';


function App() {
  const [todos, setTodos] = useState([]);
  const [inputValue, setInputValue] = useState('');

  // 添加
  const handleAddTodo = () => {
    if (inputValue.trim() !== '') {
      setTodos([...todos, { inputValue, isClick: false }]);
      console.log(todos, '...')
      setInputValue('');
    }
  };
  // 删除
  const handleDeleteTodo = (index) => {
    const newTodos = [...todos];
    newTodos.splice(index, 1);
    setTodos(newTodos);
  };
  // 完成
  const handleDoneTodo = (index) => {
    const newTodos = [...todos];
    newTodos[index].isClick = true;
    setTodos(newTodos);
  }

  return (
    <div className="App">
      <h1>Todo List</h1>
      <ul>
        {todos.map((todo, index) => (
          <li key={index} style={{ color: todo.isClick ? 'red' : 'black' }}>
            {todo.inputValue}
            <button onClick={() => handleDeleteTodo(index)}>Delete</button>
            <button onClick={() => handleDoneTodo(index)}>Done</button>
          </li>
        ))}
      </ul>
      <input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} />
      <button onClick={handleAddTodo}>Add Todo</button>
    </div>
  );
}

export default App;

小结

真的比较简单和基础了,当时自己写的时候其实也快出来了,可能是因为面试过程中敲代码多多少少有些紧张,结果一面完后我的思路就清晰了,就完成,但为时已晚了...😭😭😭

也为jym提供一个前车之鉴了~