[英]Is it good Practice to Stringify Object for useState() Hook To Avoid Re-Rendering
[英]Why is my empty object in useState hook rendering?
我只是在功能组件上刷新自己并反应 state 挂钩,构建一个简单的反应待办事项列表应用程序 - 所有简单的功能都已构建,但我在初始 state 中有一个错误,其中列表中有一个空任务渲染。 我错过了什么? 任何帮助将不胜感激。 :)
应用程序.js:
import TodoList from './TodoList'
function App() {
return (
<div>
<TodoList />
</div>
);
}
export default App;
Todolist.js:
import React, {useState} from 'react'
import NewTodoForm from './NewTodoForm'
import Todo from './Todo'
const TodoList = () => {
const [state, setState] = useState({
list: [{title: "", id: ""}]
})
const addTodo = (newTodo) => {
setState({
list: [...state.list, newTodo]
})
console.log('after state change in addtodo', state.list.title)
}
const remove = (toDoId) => {
console.log('logging remove')
setState({
list: state.list.filter(todo => todo.id !== toDoId)
})
}
const strike = e => {
const element = e.target;
element.classList.toggle("strike");
}
const update = (id, updatedTask) => {
//i cant mutate state directly so i need to make a new array and set that new array in the state
const updatedTodos = state.list.map(todo => {
if (todo.id === id) { // find the relevant task first by mapping through existing in state and add updated info before storing it in updatedtodos
return { ...todo, title: updatedTask}
}
return todo
})
console.log('updated todos', updatedTodos)
setState({
list: updatedTodos
})
console.log('list after updating state')
}
return (
<div className="TodoList">
<h1>Todo List<span>A simple react app</span></h1>
<NewTodoForm addingTodo={addTodo}/>
{ state.list.map(todo => <Todo id={todo.id} key={todo.id} title={todo.title} updateTodo={update} strikeThrough={strike} removeTodo={() => remove(todo.id)} />) }
</div>
)
}
export default TodoList
Todo.js:
import React, {useState} from 'react'
const Todo = ({id, title, removeTodo, strikeThrough, updateTodo}) => {
const [state, setState] = useState({
isEditing: false,
})
const [task, setTask] = useState(title);
const handleUpdate = (e) => {
e.preventDefault()
updateTodo(id, task)
setState({ isEditing: false})
}
const updateChange = (e) => {
// setState({...state, [e.target.name]: e.target.value})
setTask(e.target.value)
console.log(task)
}
return (
<div>
{state.isEditing ?
<div className="Todo">
<form className="Todo-edit-form" onSubmit={handleUpdate}>
<input
type="text"
value={task}
name="task"
onChange={updateChange}
>
</input>
<button>Submit edit</button>
</form>
</div> :
<div className="Todo">
<ul>
<li className="Todo-task" onClick={strikeThrough}>{title}</li>
</ul>
<div className="Todo-buttons">
<button onClick={() => setState({isEditing: !state.isEditing})}><i class='fas fa-pen' /></button>
<button onClick={removeTodo}><i class='fas fa-trash' /></button>
</div>
</div>
}
</div>
)
}
export default Todo
TodoList 中最初的 state 似乎有 list:[{title: "", id: ""}],其中包含空标题和 id。 由于它被映射为创建 Todo,我认为它从一个空的 Todo 开始。
你正在渲染你的待办事项:
{ state.list.map(todo => <Todo id={todo.id} key={todo.id} title={todo.title} updateTodo={update} strikeThrough={strike} removeTodo={() => remove(todo.id)} />) }
您最初的 state 是:
{ list: [{title: "", id: ""}] }
上面的 state 会导致 React 为你渲染一个空的待办事项。 清除阵列后,您应该看不到任何东西。 另一种选择是更改您的渲染并添加一个条件来检查待办事项值是否为空,而不是渲染它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.