React JS 中的状态正在被删除
Posted
技术标签:
【中文标题】React JS 中的状态正在被删除【英文标题】:State is being deleted in React JS 【发布时间】:2021-03-13 06:55:58 【问题描述】:我是 React 新手。我正在尝试制作一个待办事项应用程序,但是每次更新状态时(我想更改一些布尔值),它都会被删除。请有人解释一下,我的代码中发生了什么,为什么它没有在函数todoDoneParent
中被删除。代码:
TodoApp 组件
class TodoApp extends Component
state =
todos: [
id: 1, body: 'First Todo', isDone: false,
id: 2, body: 'Second Todo', isDone: false,
id: 3, body: 'Third Todo', isDone: false
]
todoDoneParent= (id) =>
let copyState = [...this.state.todos];
let todo = copyState.filter(todo => todo.id == id );
todo[0].isDone = true;
let todos = copyState.filter(todo => todo.id != id );
this.setState( todos: todo, todos );
console.log('INSIDE todoDoneParent', this.state.todos);///////////////////////////////FIRST PRINT
render()
console.log('INSIDE TodoApp.render()', this.state.todos); ///////////////////////////////SECOND PRINT
return (
<div className="allTodos">
<Todos allTodos=this.state.todos todoDoneParent=this.todoDoneParent></Todos>
</div>
);
待办事项组件
class Todos extends Component
todoDone = (e) =>
this.props.todoDoneParent(e.target.id);
render()
const todos= this.props.allTodos;
const list = todos.length ? (
todos.map(todo =>
if(todo.isDone === false)
return(<div className='todo' key=todo.id>
<div className='todo-container'>
<div>
<p>todo.body</p>
</div>
<button className='btn' id=todo.id onClick=this.todoDone>
Done
</button>
</div>
</div>)
)
) : (
<div>
<p>No todos</p>
</div>
);
return(
<div className='content'>
list
</div>
);
输出(在控制台中)
刚渲染时
INSIDE TodoApp.render()
(3) […, …, …]
0: id: 1, body: "First Todo", isDone: false
1: id: 2, body: "Second Todo", isDone: false
2: id: 3, body: "Third Todo", isDone: false
length: 3
__proto__: Array(0)
当我点击任何按钮时
INSIDE todoDoneParent
(3) […, …, …]
0: id: 1, body: "First Todo", isDone: false
1: id: 2, body: "Second Todo", isDone: false
2: id: 3, body: "Third Todo", isDone: true
length: 3
__proto__: Array(0)
INSIDE TodoApp.render()
(2) […, …]
0: id: 1, body: "First Todo", isDone: false
1: id: 2, body: "Second Todo", isDone: false
length: 2__proto__: Array(0)
那么为什么当我点击按钮 ```Done``` 时,它会在 ```todoDoneParent``` 函数中更新状态,但是,当它要被渲染时,我更新的那些状态会被删除?
【问题讨论】:
this.setState( todos: todo, todos );
只是用todos
覆盖this.state.todos
,这会过滤掉您想要标记为完成的那个。你希望这个函数做什么?
@DrewReese 我希望这个函数将isDone
变量更新为true
【参考方案1】:
问题
this.setState( todos: todo, todos );
只是用todos
覆盖this.state.todos
,这会过滤掉您想要标记为完成的那个。它将它从todos
数组中删除。
另一个问题是类型比较问题,您的待办事项的id
类型是“数字”,但从onClick
事件返回的id
字段是类型“字符串”。 ===
使用类型相等,即5 === '5'
为假,但5 == '5'
。
解决方案
如果我理解正确,您只是想将特定 todo 的 isDone
属性切换到 true
,那么您应该将旧的 todos
映射到新的 todos
并在 @987654335 时更新特定的 todo @ 匹配。
待办事项
todoDoneParent = (id) =>
this.setState((prevState) => (
todos: prevState.todos.map((todo) =>
todo.id === id
?
...todo,
isDone: true
: todo
)
));
;
待办事项
将id
值转换回数字类型,以便在父组件中进行比较。
todoDone = (e) =>
const id = e.target;
this.props.todoDoneParent(Number(id));
【讨论】:
谢谢,但它没有更新任何东西,哪里有错误?我的意思是在我的代码中。 @mecdeality===
进行严格的类型比较,即5 === '5'
为假,但5 == '5'
为真,即'==' 尝试为比较进行类型强制。任务的id
是typeof "number",但e.target.id
是typeof "string",所以todo.id === id
条件始终是false
并且没有任何更新.. 你可以强制它返回一个数字:@ 987654346@ 然后===
将起作用。【参考方案2】:
将todoDoneParent
内部更改为此,这将起作用。您只需映射待办事项并更新待办事项并返回新列表。
todoDoneParent= (id) =>
const updatedState = this.state.todos.map((item) =>
if (item.id === id)
return
...item,
isDone: true
return item;
);
this.setState( todos: updatedState );
【讨论】:
以上是关于React JS 中的状态正在被删除的主要内容,如果未能解决你的问题,请参考以下文章
如何从 React 状态数组中删除组件而不删除数组的其余部分?