【问题标题】:Update object from input without setState从没有 setState 的输入更新对象
【发布时间】:2021-07-21 05:27:39
【问题描述】:

我是 React JS(和一般的 JS)的新手。现在我正在尝试编写一个简单的任务跟踪器。

所以,我在 MyTodoList 类的状态元素中有所有任务。在那里,我使用 Task 常量分别绘制每个任务。

我想用 2 个输入实现添加一个新任务:名称和描述。

我在 MyTodoList 中创建一个新对象 (newTask),以便稍后将其添加到 state 列表中。但是,我想我正在为输入错误编写 onChange 方法。 newTask 似乎在函数内部更新(将其记录在控制台中),但它在外部没有改变(在输入空间中,输入没有变化)。显然我不能使用 setState 因为我想更新一个非状态对象(对象是可变的,所以我不明白为什么它不会改变)。

我不确定我是否错误地更新了对象,或者我添加新任务的整个概念是否错误。如果您能解释我的错误,将不胜感激。

代码如下:

const TaskAdd = ({value, onChange, placeholder, name}) => {
  return (
      <input value={value} onChange={onChange} placeholder={placeholder} name={name}/>
  )
}


const Task = ({id, name,  description, completed}) => {
    const handleClick = () => {
    }
  
    return (
      <div className='task'>
        <h3>{name}</h3>
        <div>{description}</div>
        <div>{completed}</div>
        <button onClick={handleClick} className='button1'>CLICK</button>
      </div>
    )
  }


class MyTodoList extends React.Component {
  state = {
    tasks: [
      {
        id: 1,
        name: 'Walk the dog',
        description: 'Have to walk the dog today',
        completed: false,
      },

    ]
  }

  maxId = this.state.tasks[this.state.tasks.length - 1].id;

  newTask = {
    id: this.maxId,
    name: '',
    description: '',
    completed: false,
  }

  handleChange = (event) => {
    const {value, name} = event.currentTarget

    this.newTask[name] = this.newTask[name] + value
  }

  render () {
    return(
      <div>
        <header><h1>TO-DO</h1></header>
        <div className='addTask'>
          <h2>Let's add something new</h2>

          <TaskAdd value={this.newTask.name} onChange={this.handleChange} 
          placeholder='Name' name='name'/>

          <TaskAdd value={this.newTask.description} onChange={this.handleChange} 
          placeholder='Description' name='description'/>
          <p> {this.newTask.name}</p>

          <button className='button1'><h3>Add</h3></button>
        </div>
        <div>{this.state.tasks.map(task => <Task id={task.id} name={task.name} 
        description={task.description} completed={task.completed}/>)}
        </div>

      </div>
      )
  }

}

const App = () => {
  return (
    <MyTodoList />
  )
}

export default App;

【问题讨论】:

  • state = { 的类语法是否有效?
  • @TJ 那些被称为"class fields"。这是 javascript 即将推出的一部分,现在可以通过转译器获得。

标签: reactjs object input


【解决方案1】:

显然我不能使用 setState,因为我想更新一个非状态对象

如果您希望屏幕更新您必须使用状态。 setState 函数是告诉 react 某些东西发生了变化并且需要重新渲染的唯一方法。

因此,扩展您的状态以在其中包含新任务:

  state = {
    tasks: [
      {
        id: 1,
        name: 'Walk the dog',
        description: 'Have to walk the dog today',
        completed: false,
      },

    ]
    newTask: {
      id: 2,
      name: '',
      description: '',
      completed: false,
    }
  }

您需要更新您的渲染函数以在状态下访问它,如下所示:

<TaskAdd 
  value={this.state.newTask.name} 
  onChange={this.handleChange} 
  placeholder='Name'
  name='name'
/>

然后当你设置状态时,复制而不是变异:

handleChange = (event) => {
  const {value, name} = event.currentTarget

  this.setState({
    newTask: {
      ...this.state.newTask,
      [name]: this.state.newTask[name] + value
    }
  });
}

您的代码没有包含 add 按钮的实现,但是当您这样做时,您可能会使用 this.state.newTask 并将其添加到 this.state.tasks 的末尾(您将制作一个副本数组,而不是改变它),然后创建一个新对象来替换 this.state.newTask


*好的,从技术上讲,有 forceUpdate,但不要使用它。

【讨论】:

  • 在极少数情况下可以使用forceUpdate,但如果你问这个问题,你可能真的不想使用它。
猜你喜欢
  • 1970-01-01
  • 2020-07-26
  • 2019-07-07
  • 1970-01-01
  • 2019-05-31
  • 2017-09-05
  • 2018-08-11
  • 2022-01-07
相关资源
最近更新 更多