首页 > 解决方案 > React Native、MobX 应用程序、Android 模拟器获取 TypeError:网络请求失败

问题描述

我从 API 获取数据,然后在我的 React Native 应用程序的 FlatList 中使用 MobX 状态管理将其渲染。在 IOS 上它运行完美,没有任何问题,但在 Android 上,数据没有呈现在屏幕上。在我尝试在没有 MobX 的情况下使用功能组件中的反应钩子来做到这一点之前。IOS 上的行为是相同的,但在 Android 上则不然。这意味着问题不在 MobX 中。流程是:

fetch request => loading spinner => render data on the screen

在android中,只是微调器正在加载,什么都没有发生,只是一个干净的屏幕,数据没有呈现。我得到错误:

TypeError: Network request failed
    at XMLHttpRequest.xhr.onerror (whatwg-fetch.js:504)
    at XMLHttpRequest.dispatchEvent (event-target.js:172)
    at XMLHttpRequest.setReadyState (XMLHttpRequest.js:580)
    at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:394)
    at XMLHttpRequest.js:507
    at RCTDeviceEventEmitter.emit (EventEmitter.js:189)
    at MessageQueue.__callFunction (MessageQueue.js:366)
    at MessageQueue.js:106
    at MessageQueue.__guard (MessageQueue.js:314)
    at MessageQueue.callFunctionReturnFlushedQueue (MessageQueue.js:105)

任何想法如何解决它? 在此处输入图像描述

Mobx商店:

import { action, observable, runInAction } from 'mobx'

class DataStore {
  @observable data = null
  @observable error = false
  @observable fetchInterval = null
  @observable loading = false

  //*Make request to API
  @action.bound
  fetchInitData() {
    const response = fetch('https://poloniex.com/public?command=returnTicker')
    return response
  }

  //*Parse data from API
  @action.bound
  jsonData(data) {
    const res = data.json()
    return res
  }

  //*Get objects key and push it to every object
  @action.bound
  mapObjects(obj) {
    const res = Object.keys(obj).map(key => {
      let newData = obj[key]
      newData.key = key
      return newData
    })
    return res
  }

  //*Main bound function that wrap all fetch flow function
  @action.bound
  async fetchData() {
    try {
      runInAction(() => {
        this.error = false
        this.loading = true
      })
      const response = await this.fetchInitData()
      const json = await this.jsonData(response)
      const map = await this.mapObjects(json)
      const run = await runInAction(() => {
        this.loading = false
        this.data = map
      })
    } catch (err) {
      console.log(err)
      runInAction(() => {
        this.loading = false
        this.error = err
      })
    }
  }

  //*Call reset of MobX state
  @action.bound
  resetState() {
    runInAction(() => {
      this.data = null
      this.fetchInterval = null
      this.error = false
      this.loading = true
    })
  }

  //*Call main fetch function with repeat every 5 seconds
  //*when the component is mounting
  @action.bound
  initInterval() {
    if (!this.fetchInterval) {
      this.fetchData()
      this.fetchInterval = setInterval(() => this.fetchData(), 5000)
    }
  }

  //*Call reset time interval & state
  //*when the component is unmounting
  @action.bound
  resetInterval() {
    if (this.fetchInterval) {
      clearTimeout(this.fetchInterval)
      this.resetState()
    }
  }
}

const store = new DataStore()
export default store

渲染组件:

class ChartsScreen extends Component {
  //*Component mount
  //*Call MobX store & setInterval
  componentDidMount() {
    this.props.store.initInterval()
  }

  //*Component unmount
  //*Call reset MobX store & setInterval
  componentWillUnmount() {
    this.props.store.resetInterval()
  }

  //*Change percent color
  percentColorHandler = number => {
    return number >= 0 ? true : false
  }

  render() {
    return (
      <View>
        <NavigationEvents
          onWillFocus={() => this.props.store.initInterval()}
          onWillBlur={() => this.props.store.resetInterval()}
        />
        {Platform.OS === 'ios' && <ProjectStatusBar />}
        <IconsHeader
          dataError={this.props.store.error}
          header="Charts"
          leftIconName="ios-arrow-back"
          leftIconPress={() => this.props.navigation.navigate('Welcome')}
        />
        <ChartsHeader />
        <ActivityIndicator
          animating={this.props.store.loading}
          color="#068485"
          style={{ top: HP('30%') }}
          size="small"
        />
        <FlatList
          data={this.props.store.data}
          keyExtractor={item => item.key}
          renderItem={({ item }) => (
            <CryptoItem
              name={item.key}
              highBid={item.highestBid}
              lastBid={item.last}
              percent={item.percentChange}
              percentColor={this.percentColorHandler(item.percentChange)}
            />
          )}
        />
      </View>
    )
  }
}

标签: javascriptandroidreact-nativefetchmobx

解决方案


推荐阅读