百度面试官 : 写一个ToDoList吧
前言
事情是这样的,当我辛辛苦苦,准备了半个月的八股文去尝试大厂面试的时候,以为靠着这些八股,手写题,就算面不到,也不至于很尴尬吧~
结果百度一面的时候,面试官一上来就叫我用脚手架自建项目写一个ToDoList。
我内心直接崩溃了😭😭(已经小半年没有写项目了)
所以现在想给自己长个记性,在背题的同时,也不要把一些最基础实战题给忽视了。
也想给jym提个醒,这真的算是很基础的项目实战题,不太熟的也要小心了,不要到时候真碰到了这类题写不出,那真的太掉价了~
所以现在来看这么一个简单的demo吧~
效果图
- 实现任务的添加,删除
- 点击done按钮能够使对应的item变色
创建react项目
npx create-react-app test
cd test
npm start
接下来你会得到这样的一个目录
实现任务的增加和删除
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提供一个前车之鉴了~
转载自:https://juejin.cn/post/7245518707581141050