Javascript 在反应、意外行为中推动数组
正在尝试创建待办事项列表应用程序 我希望我的todo项目具有唯一的键/id。我希望通过获取最后一个todo项目并将1添加到其id来创建todo项目id。如果该项目不存在,它将创建一个id为1的新项目 App.js:Javascript 在反应、意外行为中推动数组,javascript,arrays,reactjs,Javascript,Arrays,Reactjs,正在尝试创建待办事项列表应用程序 我希望我的todo项目具有唯一的键/id。我希望通过获取最后一个todo项目并将1添加到其id来创建todo项目id。如果该项目不存在,它将创建一个id为1的新项目 App.js: import React, {Component} from 'react'; import Todos from './Todos' import AddTodo from './AddForm' class App extends Component { state =
import React, {Component} from 'react';
import Todos from './Todos'
import AddTodo from './AddForm'
class App extends Component {
state = {
todos: [
{id: 1, content: 'buy milk'},
{id: 2, content: 'play nintendo'}
]
}
addTodo = (todo) => {
if (this.state.todos[0])
{
todo.id = this.state.todos[this.state.todos.length-1].id +1;
let todos = [...this.state.todos];
todos.push(todo);
this.setState({
todos: todos
});
}
else
{
this.setState({
todos: [
{id: 1, content: todo.content}
]
});
}
console.log(this.state.todos);
}
render() {
return(
<div className="todo-app container">
<h1 className="center blue-text">Todos:</h1>
<Todos deleteTodo={this.deleteTodo} todos={this.state.todos}/>
<AddTodo addTodo={this.addTodo} />
</div>
);
}
}
相同的content console.log:
0: {content: "buy milk", id: 1}
1: {content: "play nintendo", id: 2}
2: {content: "adrfhahhafafdhafhafhhfa", id: 3}
3: {content: "adrfhahhafafdhafhafhhfaafhafhfah", id: 4}
4: {content: "adrfhahhafafdhafhafhhfaafhafhfahafhfahafh", id: 5}
5: {content: "adrfhahhafafdhafhafhhfaafhafhfahafhfahafhafhafhfah", id: 6}
0: {content: "buy milk", id: 1}
1: {content: "play nintendo", id: 2}
2: {content: "adrfhahhafafdhafhafhhfa", id: 3}
3: {content: "adrfhahhafafdhafhafhhfaafhafhfah", id: 4}
4: {content: "adrfhahhafafdhafhafhhfaafhafhfahafhfahafh", id: 5}
5: {content: "adrfhahhafafdhafhafhhfaafhafhfahafhfahafhafhafhfah", id: 7}
6: {content: "adrfhahhafafdhafhafhhfaafhafhfahafhfahafhafhafhfah", id: 7}
如您所见,如果内容相同,则id相同
我知道这可能是在react中添加id:s的错误方法,但我想了解发生了什么。提前谢谢
编辑:Yevgen指出,如果删除项目,我的逻辑有一个缺陷,但我仍然不明白为什么会重复ID:s。有人要求提供其余的代码,所以我添加了所有代码
AddForm.js
import React, {Component} from 'react';
class AddTodo extends Component {
state = {
content: ''
}
handleChange = (e) => {
this.setState({
content: e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
this.props.addTodo(this.state);
}
render(){
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>Add new todo</label>
<input type="text" onChange={this.handleChange} />
</form>
</div>
);
}
}
export default AddTodo;
import React,{Component}来自'React';
类AddTodo扩展组件{
状态={
内容:“”
}
handleChange=(e)=>{
这是我的国家({
内容:e.target.value
});
}
handleSubmit=(e)=>{
e、 预防默认值();
this.props.addTodo(this.state);
}
render(){
返回(
添加新待办事项
);
}
}
导出默认AddTodo;
Todos.js
import React from 'react'
const Todos = ({todos, deleteTodo}) => {
const todoList = todos.length ? (
todos.map(todo => {
return (
<div className="collection-item" key={todo.id}>
<span onClick={() => {deleteTodo(todo.id)}}>{todo.content}</span>
</div>
)
})
) : (
<p className="center">You have no todos left</p>
)
return (
<div className="todos collection">
{todoList}
</div>
)
}
export default Todos;
从“React”导入React
常量Todos=({Todos,deleteTodo})=>{
const todoList=todos.length(
todos.map(todo=>{
返回(
{deleteTodo(todo.id)}>{todo.content}
)
})
) : (
您没有待办事项了
)
返回(
{托多利斯特}
)
}
导出默认TODO;
我猜您的问题来自于声明以避免对类方法使用箭头符号的方式。相反,您应该将它们声明为常规函数,并在构造函数体中为您声明的每个方法执行一些操作,如this.addTodo=this.addTodo.bind(this)
。否则,如果您非常喜欢箭头函数,您可能会更喜欢使用函数组件
按照逻辑分配自动递增的id
(因此,已删除项目的id
)并将属性为content
的对象传递给addTodo()
,您可以简单地执行以下操作:
addTodo({content}){
const id = Math.max(...this.state.todos.map(({id}) => id),0)+1
this.setState({todos:[...this.state.todos, {id, content}]})
}
我能够通过修复以下问题使其正常工作:
if (this.state.todos[0])
{
todo.id = this.state.todos[this.state.todos.length-1].id +1;
let todos = [...this.state.todos];
todos.push(todo);
this.setState({
todos: todos
});
}
为此:
if (Array.isArray(this.state.todos) && this.state.todos.length)
{
todo.id = Math.max(...this.state.todos.map(({id}) => id),0)+1
let todos = [...this.state.todos];
todos.push({id: todo.id, content: todo.content})
this.setState({
todos: todos
})
}
Yevgen指出了我在删除todo列表项时的id名称问题。我修好了。多谢各位
重复的id名称不知何故与我推动数组的方式有关。。。我仍然不能完全理解它,但它现在可以工作了。问题似乎在于调用addTodo
时传递的todo。由于todo数组或单个todo正在传递给AddTodo
组件,我想知道在调用AddTodo(?)
时,您传递给它的是什么。你能分享这部分代码吗?Thanks@AmerllicA我知道它没有遵循通常的模式,但是如果你确定你正在变异的对象是新的并且没有处于状态,它会造成什么伤害?有时,带有突变的代码的逻辑比没有突变的代码更清晰(尽管这不是一个很好的例子,因为这里使用rest语法很容易)@Alvaro I添加了代码的其余部分。我仍然不明白为什么ID:S是重复的,如果内容是相同的…@ Asistixasa:请考虑我的更新答案的建议。希望现在我能彻底解决你所有的困惑。希望,它终于让我接受了;)虽然这看起来是一个改进,但我不确定它是否回答了为什么ID会重复的问题-但问题中似乎没有足够的信息来回答真正的问题谢谢。我意识到我在删除项目时使用数组逻辑所犯的错误。不过我还是很困惑。我使用箭头函数的原因是为了访问类“this.state.”。如果我在我的类中使用你的函数,它会给我一个错误:“this.state.todos not defined”。。。有什么建议吗?