内置的React App可以正常运行,但是在开发模式下npm start的同一个App不能正常运行

问题描述

我是React和制作前端应用程序的初学者,所以我决定学习this youtube react tutorial。我对html,js和css有一些了解。

链接导致我遇到问题的课程(在React中练习state)。问题是:

onChange分配给复选框的功能在通过以下方式启动应用程序时:npm start正在起作用... 奇怪。如果执行相同的功能,则可以正常工作:npm run buildserve -s build

在本教程中,一切正常,我已经检查了我的代码,它与本教程中的100%相同。我还将我的源代码发送给了一位同事,并且...一切都按教程中的方式工作(我们都安装了Windows 10)。

当尝试通过serve -s build启动应用程序时,我鼓励在this question的帮助下解决的另一个问题(在该系统上脚本的执行已禁用-我已经在Windows powerShell中运行Set-ExecutionPolicy RemoteSigned

我还尝试删除 node_modules 并运行npm install

App.js(我已经删除了App.js的导入和导出):

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      todos: checklist
    }
    this.handleChange = this.handleChange.bind(this)
  } 
  handleChange(id) {
    console.log("debug1",id)
    this.setState(prevstate => {
      const updatedTodos = prevstate.todos.map(todo => {
        if (todo.id === id) {
          console.log(todo.id,id,todo.isChecked)
          todo.isChecked = !todo.isChecked
          console.log(todo.id,todo.isChecked)
        }
        console.log(todo)
        return todo
      })
      console.log(updatedTodos)
      return {
        todos: updatedTodos
      }
    })
  }
  render() {
    const todoChecklist = this.state.todos.map(item => <TodoItm key={item.id} item={item} 
      handleChange={this.handleChange.bind(this)}/>)
    return(
      <div>
        {todoChecklist}
      </div>
    )
  }
}

checklist.js是带有 TodoItems

集合的json文件

TodoItm(导出和导入也已删除):

function TodoItm(props) {
    return (
        <div className="todo-item">
            <h1>{props.item.line}</h1>
            <input 
                type="checkBox" 
                checked={props.item.isChecked}
                onChange={() => props.handleChange(props.item.id)} 
            />
        </div>
    )
}

PS。 我的意思是奇怪-这是我单击第一个复选框时发生的情况:

clicking first checkbox

解决方法

所以基本上你在这里改变了反应状态的原始对象,这不是正确的做法,你需要做的就是在这个todos数组中克隆这些对象。你可以按照下面的代码进行操作。以更有效的方式编写,但对于初学者来说可以,请阅读此https://seaborn.pydata.org/generated/seaborn.scatterplot.html

import React from 'react';

function ToDoItm(props) {
  return (
    <div className="todo-item">
      <h1>{props.item.line}</h1>
      <input
        type="checkbox"
        checked={props.item.isChecked}
        onChange={() => props.handleChange(props.item.id)}
      />
    </div>
  )
}

class App extends React.Component {
  constructor() {
    super()
    this.state = {
      todos: [{ id: 1,line: '1' },{ id: 2,line: '2' },{ id: 3,line: '3' },{ id: 4,line: '4' }]
    }
    this.handleChange = this.handleChange.bind(this)
  }
  handleChange(id) {
    console.log("debug1",id)
    this.setState(prevState => {
      const updatedToDos = prevState.todos.map(todo => {
        // change that i made to clone object inside todos array
        const newtodo = Object.assign({},todo);
        if (newtodo.id === id) {
          console.log(newtodo.id,id,newtodo.isChecked)
          newtodo.isChecked = !newtodo.isChecked
          console.log(newtodo.id,newtodo.isChecked)
        }
        console.log(todo)
        return newtodo
      })
      console.log(updatedToDos)
      return {
        todos: updatedToDos
      }
    })
  }
  render() {
    const todoChecklist = this.state.todos.map(item => <ToDoItm key={item.id} item={item}
      handleChange={this.handleChange.bind(this)} />)
    return (
      <div>
        {todoChecklist}
      </div>
    )
  }
}

export default App;

您将看到如何在handleChange函数中克隆那些对象并返回没有引用原始React State的newObject,您可以使用其他方法来克隆内部对象。

检查您的主应用程序是否没有包裹在严格模式下

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,document.getElementById('root')
);  

StrictMode两次调用您的App的构造函数和其他方法(仅在开发中),以确保没有副作用。尝试删除StrictMode,看看是否有帮助。

,

因此,我在this blog post上找到了答案。

事实证明,当您使用以下命令创建React应用时:npx create-react-app调用ReactDOM.Render时的App.js组件-被React.StrictMode包裹

ReactDOM.render(
  <React.StrictMode>
    <App />,</React.StrictMode>,document.getElementById('root')
);

有关该包装的发行说明说:

React.StrictMode是一个包装程序,可帮助为异步渲染准备应用程序

React.StrictMode是两次重新呈现应用程序的来源,因此是问题的根源。

在博客文章上,您可以阅读:

使用React.StrictMode可以带来的好处之一是,它可以帮助我们检测渲染阶段生命周期中的意外副作用。

但是生命周期超过了我目前对React的了解。

您也可以阅读React.StrictMode documentation

删除此包装器即可解决此问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...