在componentDidMount中,我输入了一个从Firebase中获取一些数据的函数,每次用户想要再次获取时都可以调用该函数。
问题是第一次获取不会更新。制作完之后,我想更新dataSource的数组,但不会更新它。它会通过加载旋转状态进行更新。
以下是代码:
constructor(props) {
super(props);
const rowHasChanged = (r1, r2) => r1 !== r2
// DataSource configured
ds = new ListView.DataSource({ rowHasChanged })
this.state = {
isLoading: true,
dataSource: ds,
};
}
componentDidMount() {
this.fetchGroups()
}
fetchGroups() {
firebase.database().ref('groups/numbers').once("value", (snap) => {
snap.forEach((snapshot) => {
firebase.database().ref('groups/' + snapshot.val()).once('value').then((snapshot) => {
getparticipant = snapshot.val().participant
var instantPrice
switch (true) {
case (getparticipant <= 3):
instantSpace= snapshot.val().spaceOne
break;
case (getparticipant <= 10):
instantSpace= snapshot.val().spaceTwo
break;
case (getparticipant <= 20):
instantSpace= snapshot.val().spaceThree
break;
case (getparticipant > 20):
instantSpace= snapshot.val().spaceFourth
break;
}
dataObject.push({
title: snapshot.val().type + ' ' + snapshot.val().brand,
groupId: snapshot.val().groupID,
description: snapshot.val().model,
icon: snapshot.val().icon,
partners: snapshot.val().participant,
finalDate: snapshot.val().timeMerge,
space: instantSpace,
photo: snapshot.val().adminPhoto
})
})
})
}).then(() => {
console.log(dataObject)
this.setState({
dataSource: ds.cloneWithRows(dataObject),
isLoading: false
})
console.log(this.state.isLoading)
console.log(this.state.dataSource)
})
}
答案 0 :(得分:3)
setState
是asynchronous operation。因此,您不会马上拥有它的最新价值。
如果需要访问其最新更改,可以使用:
this.setState({
dataSouce: ds.cloneWithRows(dataObject),
isLoading: false,
}, () => {
console.log(this.state.isLoading)
console.log(this.state. dataSource)
})
const asyncOperation = () => new Promise(resolve => setTimeout(resolve, 2000))
class App extends React.Component {
constructor() {
super()
this.state = {
loading: false,
counter: 0
}
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState({ loading: true })
asyncOperation()
.then(() => {
console.log('Current state value:', this.state.counter)
this.setState({
counter: this.state.counter + 1,
loading: false,
}, () => {
console.log('New state value:', this.state.counter)
})
})
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Click-me
</button>
<p>Counter: {this.state.counter}</p>
{this.state.loading && <p>Loading...</p>}
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
答案 1 :(得分:0)
尝试使用空白列表来初始化您的状态:
this.ds = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
});
this.state = {
dataSource: this.ds.cloneWithRows([]),
isLoading: true
};
请注意[]
函数内部的空白cloneWithRows
。
然后,创建一个新数组,并在获取数据时将其推送到新数组,并使用Object.assign
方法更新状态。
像这样:
fetchGroups() {
var dataObject = []
firebase.database().ref('groups/numbers').once("value", (snap) => {
snap.forEach((snapshot) => {
firebase.database().ref('groups/' + snapshot.val()).once('value').then((snapshot) => {
getparticipant = snapshot.val().participant;
var instantSpace;
switch (true) {
case (getparticipant <= 3):
instantSpace= snapshot.val().spaceOne
break;
case (getparticipant <= 10):
instantSpace= snapshot.val().spaceTwo
break;
case (getparticipant <= 20):
instantSpace= snapshot.val().spaceThree
break;
case (getparticipant > 20):
instantSpace= snapshot.val().spaceFourth
break;
}
dataObject.push({
title: snapshot.val().type + ' ' + snapshot.val().brand,
groupId: snapshot.val().groupID,
description: snapshot.val().model,
icon: snapshot.val().icon,
partners: snapshot.val().participant,
finalDate: snapshot.val().timeMerge,
price: instantPrice,
photo: snapshot.val().adminPhoto
});
// Update the state
this.setState({
dataSource: this.ds.cloneWithRows(Object.assign({}, dataObject))
});
});
});
});
}
答案 2 :(得分:0)
再次遇到此问题后,我出于专业原因进行了搜索,这就是答案:JavaScript中的对象指向内存中的位置,然后其他对象将值保存在内存中,因此可以将值复制到新的内存位置,但是对象不是,它们引用创建对象时值在内存中的位置。因此,为了复制对象,Object.assign({},obj)可以完成这项工作,或者另一个更清洁的解决方案是编写{... obj}。