Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在启动时从api获取所有数据_Javascript_Reactjs_Recursion_Fetch Api - Fatal编程技术网

Javascript 在启动时从api获取所有数据

Javascript 在启动时从api获取所有数据,javascript,reactjs,recursion,fetch-api,Javascript,Reactjs,Recursion,Fetch Api,首先,我想让您知道我只是从React和contextapi开始 以下是我的情况:我想在应用程序启动时从中取出所有啤酒(在取出时显示加载器),并将所有这些啤酒放在上下文中以访问子组件 我的问题是API没有给出所有beers页面的总数,所以我必须检查结果的长度,当长度等于0时停止抓取,然后将数据置于状态 然后,一旦加载了所有内容,我想向所有啤酒添加一个属性(favorite),并首先将其设置为false,然后,如果用户登录,检索他的收藏夹,并在与收藏夹列表相关的上下文中将其设置为true 以下是我目

首先,我想让您知道我只是从React和contextapi开始

以下是我的情况:我想在应用程序启动时从中取出所有啤酒(在取出时显示加载器),并将所有这些啤酒放在上下文中以访问子组件

我的问题是API没有给出所有beers页面的总数,所以我必须检查结果的长度,当长度等于0时停止抓取,然后将数据置于状态

然后,一旦加载了所有内容,我想向所有啤酒添加一个属性(favorite),并首先将其设置为false,然后,如果用户登录,检索他的收藏夹,并在与收藏夹列表相关的上下文中将其设置为true

以下是我目前的情况:


在这个错误中,它表示您试图在defaultBeersContext中循环通过空beers=null数组

我认为您的意图是从API加载啤酒数据以填充啤酒的状态,然后通过填充的啤酒数组forEach

出现错误是因为以下行是异步的,并且在您尝试访问其返回的数据之前未完成:

this.fetchAllBeers(1, []).then(result => this.setState({beers: result}))
因此在下一行

this.state.beers.forEach(...)
该状态仍然包含旧的默认啤酒默认数据(啤酒:null),因为您的前一行尚未完成啤酒数据的获取

如果您使用的是Promissions,那么在运行forEach之前,您需要等待获取新的beers数据,如下所示:

this.fetchAllBeers(1, [])
    .then(result => {
        this.setState({beers: result});
        allBeers.forEach(beer => (beer.favorite = false));
        ...
        })

您之所以想这样做,是因为您的以下行取决于获取啤酒数据的完成。

谢谢您@Shawn Andrews的帮助,我现在更了解承诺背后的过程。我最终决定将我的收藏夹和啤酒合并到一个儿童容器组件中,让beersContext获取所有内容,userContext获取收藏夹。然后,容器组件将两者合并,然后将修改后的值传递给渲染组件

这是我最后的啤酒背景:

import React from 'react'
import {jsonFetch} from 'easyfetch'
import _ from 'lodash'
import {UserAuthContext} from './UserContext'

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
  }

  componentDidMount() {
    this.fetchAllBeers(1, [])
  }

  async fetchAllBeers(page, beers) {
    await jsonFetch(`https://api.punkapi.com/v2/beers?page=${page}&per_page=80`)
      .get()
      .then(data => {
        if (data && data.length > 0) {
          data.forEach(item => (item.favorite = false))
          this.fetchAllBeers(page + 1, _.concat(beers, data))
        } else {
          this.setState({beers, isFetchingBeers: false})
        }
      })
      .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, fetchAllBeers: this.fetchAllBeers}}>
        {children}
      </BeersContext.Provider>
    )
  }
}

BeersProvider.contextType = UserAuthContext
从“React”导入React
从“easyfetch”导入{jsonFetch}
从“lodash”导入
从“./UserContext”导入{UserAuthContext}
常量defaultBeersContext={
啤酒:零,
是的,
errorFetchingBeers:null,
}
export const BeersContext=React.createContext(defaultBeersContext)
导出默认类BeersProvider扩展React.Component{
建造师(道具){
超级(道具)
this.state=defaultBeersContext
}
componentDidMount(){
这个。获取所有啤酒(1,[])
}
异步获取所有啤酒(第页,啤酒){
等待jsonFetch(`https://api.punkapi.com/v2/beers?page=${page}&per_page=80`)
.get()
。然后(数据=>{
如果(数据和数据长度>0){
data.forEach(item=>(item.favorite=false))
this.fetchAllBeers(第+1页,u.concat(啤酒,数据))
}否则{
this.setState({beers,isFetchingBeers:false})
}
})
.catch(error=>this.setState({errorFetchingBeers:error,isFetchingBeers:false}))
}
render(){
const{children}=this.props
const{beers,isFetchingBeers,errorFetchingBeers}=this.state
返回(
{儿童}
)
}
}
BeersProvider.contextType=UserAuthContext
this.fetchAllBeers(1, [])
    .then(result => {
        this.setState({beers: result});
        allBeers.forEach(beer => (beer.favorite = false));
        ...
        })
import React from 'react'
import {jsonFetch} from 'easyfetch'
import _ from 'lodash'
import {UserAuthContext} from './UserContext'

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
  }

  componentDidMount() {
    this.fetchAllBeers(1, [])
  }

  async fetchAllBeers(page, beers) {
    await jsonFetch(`https://api.punkapi.com/v2/beers?page=${page}&per_page=80`)
      .get()
      .then(data => {
        if (data && data.length > 0) {
          data.forEach(item => (item.favorite = false))
          this.fetchAllBeers(page + 1, _.concat(beers, data))
        } else {
          this.setState({beers, isFetchingBeers: false})
        }
      })
      .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, fetchAllBeers: this.fetchAllBeers}}>
        {children}
      </BeersContext.Provider>
    )
  }
}

BeersProvider.contextType = UserAuthContext