Javascript react中setState代码的奇怪双重执行
我有一个组件,它显示一些待办事项列表,如Javascript react中setState代码的奇怪双重执行,javascript,reactjs,setstate,Javascript,Reactjs,Setstate,我有一个组件,它显示一些待办事项列表,如 const todosData=[ { id:1, 文字:“拿出垃圾”, 已完成:正确 }, { id:2, 文字:“杂货店购物”, 已完成:false }, ]; 我有一个按钮可以触发一个简单的更改:它将char“1”添加到第一个元素的text属性中。我的处理器看起来像这样 handleChange(){ this.setState(prevState=>{ const updatedTodos=prevState.todos.map(todo=>{
const todosData=[
{
id:1,
文字:“拿出垃圾”,
已完成:正确
},
{
id:2,
文字:“杂货店购物”,
已完成:false
},
];
我有一个按钮可以触发一个简单的更改:它将char“1”添加到第一个元素的text属性中。我的处理器看起来像这样
handleChange(){
this.setState(prevState=>{
const updatedTodos=prevState.todos.map(todo=>{
如果(todo.id==1){
todo.text+=1
console.log(todo.text)
//这是我拿出来的垃圾1,拿…垃圾111,拿…垃圾11111等等
}
返回待办事项
})
返回{
待办事项:更新的待办事项
}
})
}
和简单的渲染
render() {
return (
<ul className="todo-list">
{this.state.todos.map(item => <li>{item.text}</li>)}
<button onClick={this.handleChange}>change me</button>
</ul>
)
}
如果我这样写的话——一切正常,这段代码中还有其他不足之处,实际上这段代码不是我的,但我只是想知道这神奇是怎么发生的:
这是一个有趣的问题。您可以尝试使用字母(或任何字符串),同样的情况也会发生。您还可以在开始处附加一个字符串,同样的事情也会发生 e、 g 我完全没有受过教育的猜测是,React内部的某个地方进行了某种字符串比较,并找出了区别;你的代码可能会修改原始对象中的字符串,在应用它的时候,它会将它应用到已经修改过的字符串 但是。。。如果我这样做:
const t = Date.now();
while(Date.now() < t + 1);
todo.text = 'a_' + todo.text + '_b_' + t;
它会发出两次警报(尽管如您所述,它只发出一次console.logs)
因此,出于某种原因,这段代码似乎确实运行了两次。我不知道为什么只有一条console.log消息。这是一个有趣的问题。您可以尝试使用字母(或任何字符串),同样的情况也会发生。您还可以在开始处附加一个字符串,同样的事情也会发生 e、 g 我完全没有受过教育的猜测是,React内部的某个地方进行了某种字符串比较,并找出了区别;你的代码可能会修改原始对象中的字符串,在应用它的时候,它会将它应用到已经修改过的字符串 但是。。。如果我这样做:
const t = Date.now();
while(Date.now() < t + 1);
todo.text = 'a_' + todo.text + '_b_' + t;
它会发出两次警报(尽管如您所述,它只发出一次console.logs)
因此,出于某种原因,这段代码似乎确实运行了两次。我不知道为什么只有一条console.log消息。我想这是因为
todo.text+=1
在向字符串添加int时,它会追加而不是增加字符串中的数字。如果您想增加,您必须单独增加数字并附加(这是您想要做的),这实际上正在发生,因为您正在使用函数设置状态。使用this.setState({todos:[]})
并使用this.state.todos
而不是prevState.todos
。我有点困惑为什么会发生这种情况。对不起,伙计们,我没什么好说的-你们的回答并不能让情况变得更清楚=)我想这是因为todo.text+=1
在向字符串添加int时,它会追加而不是增加字符串中的数字。如果您想增加,您必须单独增加数字并附加(这是您想要做的),这实际上正在发生,因为您正在使用函数设置状态。使用this.setState({todos:[]})
并使用this.state.todos
而不是prevState.todos
。我有点困惑为什么会发生这种情况。对不起,伙计们,我没什么好说的-你们的回答并不能让情况变得更清楚=)
todo.text = 'a_' + todo.text + alert(todo.text);