Reactjs onChange()激发两次,使得无法更改复选框(react应用程序)

Reactjs onChange()激发两次,使得无法更改复选框(react应用程序),reactjs,Reactjs,我做了一个关于Scrimba的教程(这是一个带有浏览器内IDE的网站),其中一个练习就是这个代码。它在那种环境下工作得很好。但当我将它导入到VS代码中并使用“npm start”运行它时,我注意到我的复选框“onChange”事件将触发两次。这导致它们无法工作,因为它们基本上会切换回起始值 在此之后,您将看到项目中两个文件中的代码App.js是定义函数handleChange()的地方。然后将其作为道具发送到TodoItem.js功能组件。只要有人单击复选框,该组件就会运行此函数。但出于某种原因

我做了一个关于Scrimba的教程(这是一个带有浏览器内IDE的网站),其中一个练习就是这个代码。它在那种环境下工作得很好。但当我将它导入到VS代码中并使用“npm start”运行它时,我注意到我的复选框“onChange”事件将触发两次。这导致它们无法工作,因为它们基本上会切换回起始值

在此之后,您将看到项目中两个文件中的代码App.js是定义函数handleChange()的地方。然后将其作为道具发送到TodoItem.js功能组件。只要有人单击复选框,该组件就会运行此函数。但出于某种原因,它连续运行了两次。我也尝试过使用onClick,同样的情况也发生了

App.js

import React from "react"
import TodoItem from "./TodoItem"
import todosData from "./todosData"

import "./style.css"

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            todos: todosData
        }
        this.handleChange = this.handleChange.bind(this)
    }
    
    handleChange(id) {
        this.setState((prevState) => {
            console.log("this gets printed 2 times")
            const updatedTodos = prevState.todos.map(todo => {
                if (todo.id === id) {
                    todo.completed = !todo.completed
                }
                return todo
            })
            return {
                todos: updatedTodos
            }
        })
    }
    
    render() {
        const todoItems = this.state.todos.map(item => <TodoItem key={item.id} item={item} handleChange={this.handleChange}/>)
        
        return (
            <div className="todo-list">
                {todoItems}
            </div>
        )    
    }
}

export default App
从“React”导入React
从“/TodoItem”导入TodoItem
从“/todosData”导入todosData
导入“/style.css”
类应用程序扩展了React.Component{
构造函数(){
超级()
此.state={
todos:todosData
}
this.handleChange=this.handleChange.bind(this)
}
手柄更换(id){
this.setState((prevState)=>{
log(“这会被打印两次”)
const updatedTodos=prevState.todos.map(todo=>{
if(todo.id==id){
todo.completed=!todo.completed
}
返回待办事项
})
返回{
待办事项:更新的待办事项
}
})
}
render(){
const todoItems=this.state.todos.map(item=>)
返回(
{todoItems}
)    
}
}
导出默认应用程序
TodoItem.js:

import React from "react"

function TodoItem(props) {
    
    const completedStyle={
        textDecoration: "line-through",
        fontStyle: "italic",
        color: "#cdcdcd"
    }
    
    
    return (
        <div className="todo-item">
            <input 
                type="checkbox" 
                checked={props.item.completed} 
                onChange={() => props.handleChange(props.item.id)}
            />
            <p style={props.item.completed ? completedStyle : null}>{props.item.text}</p>
        </div>
    )
}

export default TodoItem 
从“React”导入React
功能待办事项(道具){
常量完成样式={
文本装饰:“线通过”,
字体:“斜体”,
颜色:“cdcdcd”
}
返回(
props.handleChange(props.item.id)}
/>

{props.item.text}

) } 将默认值导出到doItem
您是否有机会将应用程序组件包装在React.StrictMode中?另外,您可以尝试将event.preventDefault()放在onChange()中。

是!由于某些原因,默认情况下会包装应用程序组件。这就是为什么会发生这种情况<代码>ReactDOM.render(,document.getElementById('root')StrictMode调用应用程序的构造函数和其他方法两次(仅在开发中),以确保没有副作用。尝试删除StrictMode,看看是否有帮助。如果我的答案是正确的,请标记为正确。请将其修复!谢谢你是上帝!!!将handleChange(id){更改为handleChange=(id)=>{