[英]React setState doesn't re-render after fetching data
如果已经提取了数据,则此代码有效。
但是如果我刷新页面并且不重新渲染元素则不起作用。
如果值得一提,我也在使用Next JS。
class Books extends Component {
constructor(props) {
super(props);
this.state = {
book: []
}
this.renderBooks= this.renderBooks.bind(this);
}
renderBooks() {
let item;
let items = [];
return new Promise((resolve, reject) => {
this.props.ids.forEach(address => {
firebase.database().ref(`/books/${address}`)
.on('value', snap => {
item = snap.val();
});
items.push(item);
})
resolve(items);
});
}
async componentDidMount() {
try {
let res = [];
res = await this.renderBooks();
console.log(res);
this.setState({ book: res });
} catch (error) {
console.log(error);
this.setState(prevState => {
return { book: 'err' }
});
}
}
render() {
return (
<div>
{ <List grid={{ gutter: 16 }}
dataSource={ this.state.book }
renderItem={ item => (
<List.Item>
<Card title={ !!item && item.title }>
...Book content...
</Card>
</List.Item>
)} />
}
</div>
);
}
}
export default Books;
是否有任何关于setState和获取我错过的数据的知识?
PS。 编辑构造函数预订:[]。
您正在使用promise初始化this.state.book
。 尝试将其设置为null
:
this.state = {
book: null
}
您无法使用承诺初始化book
。 相反,你可以有一个像下面的解决方案。
向render
方法添加条件渲染,以便知道何时渲染book
。 在这种情况下,您也不需要返回new Promise
。
class Books extends Component {
constructor(props) {
super(props);
this.state = { books: null }
}
componentDidMount() {
this.renderBooks()
}
renderBooks() {
this.props.ids.forEach(address => {
firebase.database().ref(`/books/${address}`)
.on('value', snap => {
this.setState({books: [...(this.state.books || []), snap.val()] });
});
});
}
render() {
return (
this.state.books ?
<div>
{ <List grid={{ gutter: 16 }}
dataSource={ this.state.books }
renderItem={ item => (
<List.Item>
<Card title={ !!item && item.title }>
...Book content...
</Card>
</List.Item>
)} />
}
</div>
: 'Initializing'
);
}
}
export default Books;
Promise基本上是异步函数,可以在时间解析。
所以,当你这样做
var item, items = []; // <---- Step 1
this.props.ids.forEach(address => {
firebase.database().ref(`/books/${address}`)
.on('value', snap => {
item = snap.val(); // <--- Step 3
});
});
items.push(item); // <----- Step 2
});
步骤是这样的。 所以你在为item分配一个新值items.push(item)
之前你正在做items.push(item)
snap.val()
。 这使得item
undefined
。
我猜你的第二个结果是由于缓存。 如果互联网连接是SOOOO FAST, Step 3
可能早于Step 2
,但这是一个不好的假设。 这就是为什么你第二次得到正确的结果。
在这个答案的情况下, snap.val()
不是有一个items
数组, snap.val()
添加到this.state.books中。 但这使它有点重量级。 因为每次调用on('value')
查询on('value')
,都会触发setState
方法并再次呈现组件。 如果有1000个国家,州将改变1000次。
这就是为什么我不建议您逐个获取所有数据,而是逐个获取数据。 尝试google类似'retrieve multiple data from firebase javascript'
。 不幸的是,我对firebase了解不多,所以无法帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.