【发布时间】:2019-04-15 21:27:09
【问题描述】:
首先,我想让你知道我刚刚开始使用 React 和 Context API。
这是我的情况:我想在应用程序启动时从PunkAPI 获取所有啤酒(在获取时显示加载器)并将所有这些啤酒放在上下文中以访问子组件。
我的问题是 API 没有给出所有啤酒页面的总数,所以我必须检查结果的长度并在长度等于 0 时停止获取,然后将数据置于状态。
然后,加载完所有内容后,我想为所有啤酒添加一个属性(favorite)并首先将其设置为 false,然后,如果用户已登录,则检索他的收藏夹,并在收藏夹列表所关注的上下文中为每种啤酒设置为 true。
这是我现在带来的:
import React from 'react'
import {jsonFetch} from 'easyfetch'
import _ from 'lodash'
import {UserAuthContext} from './userContext'
import {db} from '../firebase'
const defaultBeersContext = {
beers: null,
isFetchingBeers: true,
errorFetchingBeers: null,
}
export const BeersContext = React.createContext(defaultBeersContext)
export default class BeersProvider extends React.Component {
constructor(props) {
super(props)
this.state = defaultBeersContext
}
async componentDidMount() {
let allBeers = await this.fetchAllBeers(1, [])
allBeers.forEach(beer => (beer.favorite = false))
console.log(allBeers.length)
console.log(allBeers)
const {isUserSignedIn, user} = this.context
if (isUserSignedIn && user) {
db.collection('users')
.doc(user.uid)
.get()
.then(doc => {
const favoriteBeers = doc.data().favorites
favoriteBeers.forEach(elem => {
const index = allBeers.findIndex(beer => beer.id === elem)
allBeers[index].favorite = true
})
})
}
this.setState({beers: allBeers, isFetchingBeers: false})
}
fetchAllBeers(page, beers) {
jsonFetch(`https://api.punkapi.com/v2/beers?page=${page}&per_page=80`)
.get()
.then(data => {
if (data && data.length > 0) {
this.fetchAllBeers(page + 1, _.concat(beers, data))
} else {
return beers
}
})
.catch(error => this.setState({errorFetchingBeers: error, isFetchingBeers: false}))
}
render() {
const {children} = this.props
const {beers, isFetchingBeers, errorFetchingBeers} = this.state
return (
<BeersContext.Provider value={{beers, isFetchingBeers, errorFetchingBeers}}>{children}</BeersContext.Provider>
)
}
}
BeersProvider.contextType = UserAuthContext
P.S:我使用的 jsonFetch 来自这里:easyfetch
但这不起作用,说:
Unhandled Rejection (TypeError): Cannot read property 'forEach' of null
21 | async componentDidMount() {
22 | this.fetchAllBeers(1, []).then(result => this.setState({beers: result}))
> 23 | this.state.beers.forEach(beer => (beer.favorite = false))
| ^ 24 | const {isUserSignedIn, user} = this.context
25 | if (isUserSignedIn && user) {
26 | db.collection('users')
【问题讨论】:
标签: javascript reactjs recursion fetch-api