所以我有一个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;
当我添加第一个数组元素时,出现错误而不是库存。然后,当我添加第二个元素时,数组将存储第一个元素。当我添加第三个元素时,数组现在仅包含第一个和第二个元素。我知道这是因为我已经在控制台中看到了
答案 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
绑定。有两种处理方法。
通过调用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>
);
}
}
由于箭头函数没有像普通函数那样具有独立的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扩展。
使用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)
}