这是父组件:
state = {
books: undefined
}
componentDidMount() {
BooksAPI.getAll().then(books => {
this.setState({books},this.filterBooks);
});
}
filterBooks() {
this.currentlyReading = this.state.books.filter((book) => book.shelf === 'currentlyReading');
this.read = this.state.filter((book) => book.shelf === 'read');
this.wantToRead = this.state.filter((book) => book.shelf === 'wantToRead');
}
render() {
return (
<div className="app">
<Route path="/search" component={SearchBook} />
<Route exact
path="/"
render={() => <BookScreen
currentlyReading={this.currentlyReading}
read={this.read}
wantToRead={this.wantToRead}
/>} />
</div>
)
}
我希望在调用filterBooks之后,
BookScreen
组件的道具会更改,并且该组件应该重新呈现,但事实并非如此。我究竟做错了什么? 最佳答案
在我看来,目前最好的方法(仍然遵循React的方法)是:在拥有books
数据之后,仅调用1函数,该函数将处理所有内容并在完成后更新状态(我们将books
对象作为参数传递), 像这样:
componentDidMount() {
BooksAPI.getAll().then(books => {
this.filterBooks({books});
});
}
filterBooks = (books) => {
this.currentlyReading = books.filter((book) => book.shelf === 'currentlyReading');
this.read = books.filter((book) => book.shelf === 'read');
this.wantToRead = books.filter((book) => book.shelf === 'wantToRead');
this.setState({ books: books });
}
如果您有任何错误,请随时在此处发布,我们可以一起解决!
========
添加了有关作者原始代码为何无效的说明:
根据我对React和JS的一点经验:
设置新状态后,可能要花费一些时间(可能是100-300ms,这就是为什么使用语法
this.filterBooks
执行原始this.setState({books},this.filterBooks)
的原因=>这似乎是正确的,这意味着在已经设置
books
的新状态之后,您可以使用filterBooks
函数访问它。)但是:设置
books
的新状态后,将重新呈现页面,并执行filterBooks
(也许在同一时间=>不确定哪个先结束,所以举个例子,例如this.currentlyReading的结果之前先出现render()
,则在render()
中仍未定义>!换句话说,React是Javascript,而Javascript的异步性很麻烦!