将阵列中的物品存放在状态

时间:2019-07-03 09:37:15

标签: javascript reactjs

所以我有一个textarea,我想将textarea的项目存储在我在应用状态内创建的数组中。昨天代码运行得很好,但是我认为我只是出于意外更改了某些内容,并且有此错误。

该代码收集文本区域内的值,然后每当我单击按钮时,就使用函数将文本区域中写入的值连接到数组的项。有app.js和task.js,其中有textarea和按钮。

tasks.js:

import React from 'react'


class Tasks extends React.Component {

    constructor(props) {
        super(props)
        this.state = {
            value: '',            
        }
    }
    handleChange = e => {
        this.setState({ value: e.target.value })
    }

    render() {
        return (<div>
            <textarea value={this.state.value} onChange={this.handleChange} ></textarea>
            <button onClick={() => this.props.onClick(this.state.value)}>Add task</button>
        </div>)

    }

}



export default Tasks

app.js:

import React from 'react';
import Tasks from './tasks.js';
import './App.css';




class App extends React.Component {
  state = {
    todolist: []
  }

  addData(val) {
    this.setState({todolist:this.state.todolist.concat(val)})
    console.log(this.state.todolist)
  }


  render() {
    return (
      <div className="App">
        <Tasks onClick={value => this.addData(value)} />

      </div>

    );
  }
}



export default App;

当我添加第一个数组元素时,出现错误而不是库存。然后,当我添加第二个元素时,数组将存储第一个元素。当我添加第三个元素时,数组现在仅包含第一个和第二个元素。我知道这是因为我已经在控制台中看到了

5 个答案:

答案 0 :(得分:2)

您的原始问题有一个错误,您已通过此修改对其进行了更正。现在唯一未解决的问题是setState maybe an async operation,因此您需要使用其回调在更新后检查状态。

addData(val) {
  this.setState({
    todolist: this.state.todolist.concat(val)
  }, () => console.log(this.state.todolist))
}

答案 1 :(得分:1)

阅读此doc

  

对setState的调用是异步的-调用setState后不要立即依赖this.state来反映新值。

答案 2 :(得分:0)

我认为您需要将App中的'addData'作为道具传递给孩子,然后将其放在handleChange上 但您在Task上将其定义为onClick事件

添加 然后在Task handleChange上添加 this.props.addData(e.target.value)

答案 3 :(得分:0)

您正在使用'{value}'在箭头函数中调用addData函数,而不是将其向下传递给<Tasks>

代替

render() {
    return (
      <div className="App">
        <Tasks onClick={value => this.addData(value)} />

      </div>

    );

只需传递对addData函数的引用,无需将其作为道具传递时就调用它或将其包装在箭头函数中。

render() {
    return (
      <div className="App">
        <Tasks onClick={this.addData} />
      </div>

    );

现在唯一的问题是因为我们删除了包裹this.addData(value)的箭头函数,因此您失去了this绑定。有两种处理方法。

选项1

通过调用this并在构造函数生命周期方法中传入当前.bind()上下文,在addData中绑定this关键字的值。

class App extends React.Component {

    constructor(props) {
      super(props);
      this.state = {
        todolist: []
      }

      addData = this.addData.bind(this);
    }

    addData(val) {
      this.setState({todolist:this.state.todolist.concat(val)})
      console.log(this.state.todolist)
    }

    render() {
      return (
        <div className="App">
          <Tasks onClick={this.addData} />
        </div>
      );
    }
}

选项2

由于箭头函数没有像普通函数那样具有独立的this上下文,因此我们可以将addData从函数声明更改为箭头函数表达式。

class App extends React.Component {

      state = {
        todolist: []
      }

    addData = (val) => {
      this.setState({todolist:this.state.todolist.concat(val)})
      console.log(this.state.todolist)
    }

    render() {
      return (
        <div className="App">
          <Tasks onClick={this.addData} />
        </div>
      );
    }
}

您应该查看Chrome的React Dev Tools扩展。

https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en

使用React Dev Tools通过console.log检查组件状态要容易得多。

答案 4 :(得分:0)

您知道javascript以异步方式运行,因此它不会等待this.setState()完成然后传递给console.log()。 您必须强迫它等待直到状态被设置。

为此,您可以像这样使用async await

async addData(val) {
    await this.setState({todolist:this.state.todolist.concat(val)})
    console.log(this.state.todolist)
  }