Jat*_*eja 4 android caching reactjs react-native redux
React原生及其概念相当新.我已经和RN一起玩了一段时间来创建一个从中获取API数据的应用程序
http://jsonplaceholder.typicode.com/photos
我一直在研究AsyncStorage的文档,以实现我如何缓存API数据,以便在终止应用程序时,它不必一次又一次地处理从web获取数据,但是无法成功实现它.
如果你可以根据它给我提供帮助/建议,那就太好了.我在我的应用程序中包含了2个重要文件的源代码,以及我试图实现的Test.js文件.
import React, {Component} from 'react';
import { FlatList, View, Text, AsyncStorage, ActivityIndicator } from 'react-native';
import axios from 'axios';
import GalleryDetail from './GalleryDetail';
class GalleryList extends Component {
state = { photos: []};
componentDidMount() {
axios.get('http://jsonplaceholder.typicode.com/photos')
.then(response => this.setState({ photos: response.data }))
.catch((error)=> console.warn("fetch Error: ", error));
}
getPhotos = async()=> {
try {
photos = await AsyncStorage.getItem('GalleryPhotos');
}
catch (error) {
console.error(error);
}
}
savePhotos(){
AsyncStorage.setItem('GalleryPhotos', this.state.photos);
console.log('works !');
}
renderPhoto = ({item})=> {
return <GalleryDetail photo={item}/>
}
keyExtractor = (photo, index) => photo.id;
render () {
if(!this.state.photos){
return <ActivityIndicator/>;
}
return (
<FlatList
data = {this.state.photos}
keyExtractor={this.keyExtractor}
renderItem={this.renderPhoto}
/>
);
}
}
export default GalleryList;
Run Code Online (Sandbox Code Playgroud)
和GalleryDetail链接GalleryList-
import React, {Component} from 'react';
import { Text, View, Image } from 'react-native';
import Card from './Card';
import CardSection from './CardSection';
const GalleryDetail = (props)=> {
return (
<Card>
<CardSection style = {styles.headerContentStyle}>
<Image
style={styles.thumbnailStyle}
source = {{ uri: props.photo.thumbnailUrl}}/>
<Text style= {styles.textStyle}>{props.photo.title} </Text>
</CardSection>
</Card>
);
};
const styles = {
headerContentStyle: {
flexDirection: 'column',
justifyContent: 'space-around'
},
thumbnailStyle: {
height: 60,
width: 60
},
textStyle: {
fontSize: 12,
//textAlign: 'right',
flexDirection: 'row',
justifyContent: 'flex-end',
flex: 1,
flexWrap: 'wrap',
marginLeft: 5,
marginRight: 5,
}
}
export default GalleryDetail;
Run Code Online (Sandbox Code Playgroud)
我的尝试方法是 - 在启动应用程序时,它将首先查看asyncStorage,如果它找到数据 - 它从异步中获取,否则进入Web,再次获取和存储以供以后使用.我试图在一个单独的文件中实现这样的,因为我想要分解我已经运行的应用程序.奇怪的破解语法是
State = {
photos: []
}
componentDidMount() {
// just a variable acting to fetch data from the stored keyvalue pair
check = AsyncStorage.getItem("PhotosKey").then((response) => {
this.setState({"PhotosKey": response});
}).done();
if(check) {
console.log('Data was fetched!!!!!');
check();
}
else {
console.log("Data was not fetched!");
var Data = axios.get('http://jsonplaceholder.typicode.com/photos').
then(response => this.setState({ photos: response.data })).
catch((error)=> console.warn("fetch Error: ", error));
}
}
Run Code Online (Sandbox Code Playgroud)
提前致谢!
async componentDidMount() {
const photoStorage = await AsyncStorage.getItem('GalleryPhotos')
if(photoStorage) {
try {
const photoResp = await axios.get('http://jsonplaceholder.typicode.com/photos')
const photoData = await JSON.stringify(photoResp.data)
await AsyncStorage.setItem('GalleryPhotos', photoData);
} catch(e) {
console.warn("fetch Error: ", error)
}
.then(response => this.setState({ photos: response.data }))
}
}
Run Code Online (Sandbox Code Playgroud)
后来
getPhotos = async()=> {
try {
photos = JSON.parse(await AsyncStorage.getItem('GalleryPhotos'));
}
catch (error) {
console.error(error);
}
}
Run Code Online (Sandbox Code Playgroud)
方法Subramanya
基本上是您开始所需的全部内容,我将介绍一种状态管理方法,redux-persist
当您的应用程序增长时,您绝对可以欣赏到这种方法。
Redux Persist具有高性能、易于实现和易于扩展的特点。
假设您的应用程序连接redux
并实现了一个相当有组织的状态树,redux-persist
存储整个应用程序状态AsyncStorage
您选择的任何存储引擎。
例如,假设您的 API 端点返回一组照片,您需要做的就是更新商店,并且您的用户可以期望他们的数据是安全的并使用redux-persist
.
我还没有测试下面的所有代码
让我们定义第store
一个,
import { AsyncStorage } from 'react-native';
import { createStore, compose, applyMiddleware, } from "redux";
import { persistStore } from "redux-persist";
import ReduxThunk from "redux-thunk";
import reducers from "../reducers"
const middleWare = [ReduxThunk]
const store = createStore(
reducers,
{},
compose(applyMiddleware(...middleWare))
)
// you can define more parameters, like blacklist or whitelist a reducer
// also, specify storage engine
persistStore(store, { storage: AsyncStorage });
export default store;
Run Code Online (Sandbox Code Playgroud)
在您的应用程序入口点,
import React, { Component } from "react";
import { Provider } from "react-redux";
import Router from "./Router";
import store from './store';
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Provider store={store}>
<Router /> // navigator
</Provider>
);
}
}
Run Code Online (Sandbox Code Playgroud)
最后,您的 API 逻辑。
// action creator
export storePhoto = photos => {
return {
type: 'STORE_PHOTOS',
payload: photos
}
}
// photos reducer
import { REHYDRATE } from 'redux-persist/constants';
export default (state = {}, action) => {
switch (action.type) {
case STORE_PHOTOS:
return { ...state, photos: action.payload }
// this is where `redux-persist` handles caching
case REHYDRATE:
var incoming = action.payload;
if(incoming) return { ...state, ...incoming }
return state;
default:
return state;
}
};
Run Code Online (Sandbox Code Playgroud)
要检索数据,您将看到 redux 抽象掉了所有多余的逻辑,没有更多,setItem, getItem
因为redux-persist
它已经为您自动执行了。
import { connect } from "react-redux";
import { storePhotos } from "./actions";
class GalleryList extends Component {
async componentDidMount() {
const photos = await axios.get('http://jsonplaceholder.typicode.com/photos');
storePhoto(photos)
}
renderPhoto = ({ item }) => <GalleryDetail photo={item}/>
keyExtractor = (photo, index) => photo.id;
render () {
return (
<FlatList
data = {this.props.photos}
keyExtractor={this.keyExtractor}
renderItem={this.renderPhoto}
/>
);
}
}
// pull data from photos reducer
const mapStateToProps = ({ photos }) => {
return {
photos: photos.photos
}
}
export default connect(mapStateToProps, { storePhotos })(GalleryList);
Run Code Online (Sandbox Code Playgroud)
总结一下,
希望我的回答有帮助!
归档时间: |
|
查看次数: |
8305 次 |
最近记录: |