我正在尝试弄清楚如何使用钩子在我的react应用程序中编辑待办事项,但似乎无法弄清楚如何编写代码。
我在网上看到的大多数解决方案都使用类组件,并且编写的逻辑与我的应用程序不同。
这是我当前的代码
function TodoList() {
const [todos, setTodos] = useState([]);
const addTodo = todo => {
if (!todo.text || /^\s*$/.test(todo.text)) {
return;
}
const newTodos = [todo, ...todos];
setTodos(newTodos);
console.log(newTodos);
};
const removeTodo = id => {
const removedArr = [...todos].filter(todoId => todoId.id !== id);
setTodos(removedArr);
};
const completeTodo = id => {
let updatedTodos = todos.map(todo => {
if (todo.id === id) {
todo.isComplete = !todo.isComplete;
}
return todo;
});
setTodos(updatedTodos);
};
const editTodo = e => {
setTodos(e.target.value);
};
return (
<>
<TodoForm onSubmit={addTodo} />
{todos.map(todo => (
<div>
<div
key={todo.id}
className={todo.isComplete ? 'complete' : ''}
key={todo.id}
onClick={() => completeTodo(todo.id)}
>
{todo.text}
</div>
<FaWindowClose onClick={() => removeTodo(todo.id)} />
</div>
))}
</>
);
}
这是其他组件中的代码
function TodoForm(props) {
const [input, setInput] = useState('');
const handleChange = e => {
setInput(e.target.value);
};
const handleSubmit = e => {
e.preventDefault();
props.onSubmit({
id: Math.floor(Math.random() * 10000),
text: input,
complete: false
});
setInput('');
};
return (
<form onSubmit={handleSubmit}>
<input
placeholder='todo...'
value={input}
onChange={handleChange}
name='text'
/>
<button onClick={handleSubmit}>add todo</button>
</form>
);
}
所以现在一切正常,在这里我可以添加待办事项和删除待办事项+删除待办事项。唯一缺少的就是能够对其进行编辑。
我看到了一些有关使用输入表单更新文本值的建议,但是我不太确定如何在editTodo函数中实现它。
答案 0 :(得分:0)
类似于removeTodo处理程序,您想将todo.id传递给completeTodo。
ESX.RegisterUsableItem('turtlebait', function(source)
local xPlayer = ESX.GetPlayerFromId(source)
if xPlayer.getInventoryItem('fishingrod').count > 0 then
TriggerClientEvent('fishing:setbait', (source, "turtle"))
xPlayer.removeInventoryItem('turtlebait', 1)
TriggerClientEvent('fishing:message', (source, "You attach the ~y~turtle bait~s~ onto your fishing rod"))
else
TriggerClientEvent('fishing:message', (source, "~r~You don't have a fishing rod"))
end
然后,您将更新todo对象中的bool值。
<div className={todo.isComplete ? "complete" : ""} key={todo.id} onClick={() => completeTodo(todo.id)}>
编辑:添加样式删除线 然后,您将根据isComplete布尔条件有条件地添加CSS样式
CSS
const completeTodo = (id) => {
let updatedTodos = todos.map(todo => {
if(todo.id === id){
todo.isComplete = true
}
return todo
})
setTodos(updatedTodos)
};
要能够单击“删除”按钮,请将其放置在地图功能中的todo div之外。
.complete {
text-decoration: line-through;
}
答案 1 :(得分:0)
与您在另一个问题中的讨论是:
TodoList.js
import React, { useState } from "react";
import TodoForm from "./TodoForm";
import Todo from "./Todo";
function TodoList({ onClick }) {
const [todos, setTodos] = useState([]);
//Track is edit clicked or not
const [editId, setEdit] = useState(false);
//Save input value in input box
const [inputValue, setInputValue] = useState("");
const handleEditChange = (id, text) => {
setEdit(id);
setInputValue(text);
};
const addTodo = (todo) => {
if (!todo.text || /^\s*$/.test(todo.text)) {
return;
}
const newTodos = [todo, ...todos];
setTodos(newTodos);
console.log(newTodos);
};
const removeTodo = (id) => {
const removedArr = [...todos].filter((todoId) => todoId.id !== id);
setTodos(removedArr);
};
const completeTodo = (id) => {
let updatedTodos = todos.map((todo) => {
if (todo.id === id) {
todo.isComplete = !todo.isComplete;
}
return todo;
});
setTodos(updatedTodos);
};
const editTodo = (id, text) => {
let editTodos = todos.map((todo) => {
if (todo.id === id) {
todo.text = text;
}
return todo;
});
setTodos(editTodos);
setEdit(false);
};
return (
<>
<TodoForm onSubmit={addTodo} />
{/* I want to move this code below into a new component called Todo.js */}
<Todo
todos={todos}
completeTodo={completeTodo}
removeTodo={removeTodo}
editTodo={editTodo}
handleEditChange={handleEditChange}
editId={editId}
inputValue={inputValue}
setInputValue={setInputValue}
/>
</>
);
}
export default TodoList;
Todo.js
// I want to move this code into this component
import React, { useState } from "react";
import { FaWindowClose, FaRegEdit } from "react-icons/fa";
const Todo = ({
todos,
completeTodo,
removeTodo,
editTodo,
editId,
handleEditChange,
inputValue,
setInputValue
}) => {
return todos.map((todo) => (
<div className="todo-row">
{editId === todo.id ? (
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
) : (
<div
key={todo.id}
className={todo.isComplete ? "complete" : ""}
onClick={() => completeTodo(todo.id)}
>
{todo.text}
</div>
)}
{editId === todo.id ? (
<button onClick={() => editTodo(todo.id, inputValue)}>Edit todo</button>
) : (
<>
<FaWindowClose onClick={() => removeTodo(todo.id)} />
<FaRegEdit onClick={() => handleEditChange(todo.id, todo.text)} />
</>
)}
</div>
));
};
export default Todo;
确保首先阅读并理解代码。您在 completeTodo 中所做的逻辑非常简单。您只需要更新文本部分。棘手的部分是在输入中打开。因此,逻辑就像跟踪如果用户单击ID设置该ID。然后检查id是否存在带有该id值的打开输入,否则将返回正常值。
以下是此POC的演示:https://codesandbox.io/s/nostalgic-silence-idm21?file=/src/Todo.js:0-1059