Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript react中setState代码的奇怪双重执行_Javascript_Reactjs_Setstate - Fatal编程技术网

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);