我在代码中遇到了一个反复出现的问题,我想从组件中获取多条数据以设置为状态,然后将它们压入一个状态已更新的数组中。我目前的工作方式目前行不通,我认为这是因为我不了解js发生事件并做出反应的顺序。
以下是我正在执行的操作的一个示例,该示例无效:jsfiddle here或下面的代码。
import React, {Component} from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
categoryTitle: null,
categorySubtitle: null,
categoryArray: [],
}
}
pushToCategoryArray = () => {
this.state.categoryArray.push({
'categoryTitle': this.state.categoryTitle,
'categorySubtitle': this.state.categorySubtitle,
})
}
setCategoryStates = (categoryTitle, categorySubtitle) => {
this.setState({
categoryTitle: categoryTitle,
categorySubtitle: categorySubtitle,
})
this.pushToCategoryArray();
}
render() {
return (
<CategoryComponent
setCategoryStates={this.setCategoryStates}
categoryTitle={'Category Title Text'}
categorySubtitle={'Category Subtitle Text'}
/>
);
}
}
class CategoryComponent extends Component {
render() {
var categoryTitle = this.props.categoryTitle;
var categorySubtitle = this.props.categorySubtitle;
return (
<div onClick={() => (this.props.setCategoryStates(
categoryTitle,
categorySubtitle,
))}
>
<h1>{categoryTitle}</h1>
<h2>{categorySubtitle}</h2>
</div>
);
}
}
我可以在控制台中看到要获取的categoryTitle
和categorySubtitle
,但是它们被作为null
推送到this.state.categoryArray
中。这是我需要使用诺言的情况吗?采取另一种方法?
答案 0 :(得分:0)
我认为React不会重新渲染,因为pushToCategoryArray直接更改了状态。需要在this.setState函数中分配新的数组。
// this.state.categoryArray.push({...})
const prevCategoryArray = this.state.categoryArray
this.setState({
categoryArray: [ newObject, ...prevCategoryArray],
)}
答案 1 :(得分:0)
发生这种情况是因为setState是异步(https://reactjs.org/docs/state-and-lifecycle.html#using-state-correctly)。
问题出在这里
//State has categoryTitle as null and categorySubtitle as null.
this.state = {
categoryTitle: null,
categorySubtitle: null,
categoryArray: [],
}
//This gets the correct values in the parameters
setCategoryStates = (categoryTitle, categorySubtitle) => {
//This is correct, you're setting state BUT this is not sync
this.setState({
categoryTitle: categoryTitle,
categorySubtitle: categorySubtitle,
})
this.pushToCategoryArray();
}
//This method is using the state, which as can be seen from the constructor is null and hence you're pushing null into your array.
pushToCategoryArray = () => {
this.state.categoryArray.push({
'categoryTitle': this.state.categoryTitle,
'categorySubtitle': this.state.categorySubtitle,
})
}
解决方案:将回调传递给setState
setCategoryStates = (categoryTitle, categorySubtitle) => {
//This is correct, you're setting state BUT this is not sync
this.setState({
categoryTitle: categoryTitle,
categorySubtitle: categorySubtitle,
}, () => {
/*
Add state to the array
This callback will be called once the async state update has succeeded
So accessing state in this variable will be correct.
*/
this.pushToCategoryArray()
})
}
并更改
pushToCategoryArray = () => {
//You don't need state, you can simply make these regular JavaScript variables
this.categoryArray.push({
'categoryTitle': this.state.categoryTitle,
'categorySubtitle': this.state.categorySubtitle,
})
}