React Native 中的 Fetch 函数,带有 mobx-react-lite 和 React 钩子



我是 mobx-react 的新手,我需要编写从 API 获取数据并将其渲染到 FlatList 的获取函数。我已经创建了获取函数,使用 useContext 钩子设置了初始状态,并通过观察者 mobx 类包装了我的应用程序。但是现在我需要实现从服务器获取数据。你能告诉我哪种方法最好吗?

import { createContext } from 'react'
import { action, decorate, observable, computed, runInAction } from 'mobx'
import fetchData from '../utils/fetchData'
import mapObjects from '../utils/mapObjects'
class DataStore {
data = null
error = false
loading = true
get getData(){
return this.data
}
get getError(){
return this.error
}
get getLoading(){
return this.loading
}
async fetchData(url) {
this.data = null
this.error = false
this.loading = true
try {
console.log('TRY')
const response = await fetch(url)
const jsonResponse = await response.json()
const obj = await mapObjects(jsonResponse)
runInAction(() => {
console.log('WRITE!!!')
this.loading = false
this.data = obj
})
} catch (err) {
runInAction(() => {
console.log(err)
this.loading = false
this.error = err
})
}
}
}
decorate(DataStore, {
data: observable,
error: observable,
loading: observable,
fetchData: action
})
export default createContext(new DataStore())

我的组件:

import React, { useContext, useEffect, useState } from 'react'
import { ActivityIndicator, FlatList, Platform, StyleSheet, View } from 'react-native'
import DataStore from '../mobx/DataStore'
import { autorun } from 'mobx'
import { ChartsHeader, CryptoItem, IconsHeader, ProjectStatusBar } from '../components'
import { useFetch } from '../hooks/useFetch'
import { WP, HP } from '../constants'
const styles = StyleSheet.create({
container: {
flex: 1
}
})
const ChartsScreen = ({ navigation }) => {
const { container } = styles
const store = useContext(DataStore)
const url = 'https://poloniex.com/public?command=returnTicker'
console.log('store', store)
useEffect(() => {
store.fetchData(url)
}, [])
//*Call custom hook and data distruction
//const { data, error, loading } = useFetch(url)
//*Change percent amount color depends on the amount
const percentColorHandler = number => {
return number >= 0 ? true : false
}
return (
<View style={container}>
{Platform.OS === 'ios' && <ProjectStatusBar />}
<IconsHeader
dataError={store.error}
header="Charts"
leftIconName="ios-arrow-back"
leftIconPress={() => navigation.navigate('Welcome')}
/>
<ChartsHeader />
<ActivityIndicator animating={store.loading} color="#068485" style={{ top: HP('30%') }} size="small" />
<FlatList
data={store.data}
keyExtractor={item => item.key}
renderItem={({ item }) => (
<CryptoItem
name={item.key}
highBid={item.highestBid}
lastBid={item.last}
percent={item.percentChange}
percentColor={percentColorHandler(item.percentChange)}
/>
)}
/>
</View>
)
}
export { ChartsScreen }

对于仍在使用 MobX 在 React 中寻找获取函数方法的每个人。我检查了很多信息,但找不到一个好的决定。但最终我创造了我的。也许它会对某人有所帮助: 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

最新更新