React Native 版本执行0.57的规则
公共方法
/**
* key-value 存储
* App用到的所有存储 key 名字在此处列出并注明 例如: userInfo 用户信息
* searchHistory 搜索历史arr
*/
import { AsyncStorage } from 'react-native';
// 设置 item
export async function setItem(key, value) {
return await AsyncStorage.setItem(key, JSON.stringify(value));
}
// 查询 item
export function getItem(key) {
return new Promise((resolve, reject) => {
AsyncStorage.getItem(key).then(data => {
resolve(JSON.parse(data))
});
})
}
// 删除 item
export async function removeItem(key) {
return await AsyncStorage.removeItem(key)
}
// 修改 item: 只能修改 json 数据,不能直接修改数组数据
export async function mergeItem(key, value) {
return await AsyncStorage.mergeItem(key, JSON.stringify(value))
}
// 数组删除一个或多个 index:从第几个开始 length:删除几个,默认为1,可不传
export function arrDelete(arr, index, length = 1) {
let tempArr = arr;
arr.splice(index, length);
return tempArr;
}
实际应用
值得注意的是,react native 的本地存储返回的是一个promise对象,关键的思路:先从缓存里去数据,赋值两种状态,然后是添加的方法,但是这个方法耦合性比较高,
还可以参考我的其他博客,这是链接?
/**
* Created by ke2933 on 2018/11/30
* 搜索页
*/
import React, { Component } from 'react';
import { StyleSheet, Text, View, ScrollView, Image, TouchableOpacity, StatusBar, TextInput } from 'react-native';
import Nav from '../../components/Nav';
import { global } from '../../utils/Global';
import Confirm from '../../components/Confirm'
import * as DataBase from '../../utils/Public'
import { requestUrl } from '../../network/Url';// 请求url
import Fetch from '../../network/Fetch';
import { NavigationEvents } from "react-navigation";
export default class Search extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
searchVal: "",// 搜索文字
hasData: false,// 删除确认弹框
searchHistory: [],// 搜索历史数组
hotTagsArr: [],// 热门搜索标签数组
}
}
componentDidMount() {
// 获取热门搜索标签
this.setState({
isLoading: true,
})
Fetch(requestUrl.queryAllHotTags).then(data => {
console.log(data)
if (data.status == "SUCCESS") {
this.setState({
isLoading: false,
hotTagsArr: data.data,
})
} else if (data.status == "ERROR") {
this.setState({
isLoading: false,
})
ToastShow({ "text": '热门标签查询失败' })
} else {
this.setState({
isLoading: false,
})
ToastShow({ "text": '热门标签查询失败' })
}
})
}
//获取历史记录
getHistory() {
// 查询本地历史
DataBase.getItem("searchHistory").then(data => {
if (data == null) {
this.setState({
searchHistory: [],
})
} else {
this.setState({
searchHistory: data,
})
}
})
}
// 保存搜索标签
insertSearch(text) {
if (this.state.searchHistory.indexOf(text) != -1) {
// 本地历史 已有 搜索内容
let index = this.state.searchHistory.indexOf(text);
let tempArr = DataBase.arrDelete(this.state.searchHistory, index)
tempArr.unshift(text);
DataBase.setItem("searchHistory", tempArr);
} else {
// 本地历史 无 搜索内容
let tempArr = this.state.searchHistory;
tempArr.unshift(text);
DataBase.setItem("searchHistory", tempArr);
}
}
render() {
const { navigate, goBack } = this.props.navigation;
return (
<View style={styles.container}>
{/* 监听页面 刷新搜索本地历史 */}
<NavigationEvents
onWillFocus={() => {
// 查询本地搜索历史
this.getHistory();
}}
/>
<StatusBar
animated={true}//是否动画
hidden={false}//是否隐藏
backgroundColor={'#000'}//android 设置状态栏背景颜色
translucent={false}//android 设置状态栏是否为透明
showHideTransition="fade"//IOS状态栏改变时动画 fade:默认 slide
networkActivityIndicatorVisible={this.state.isLoading}//IOS设定网络活动指示器(就是那个菊花)是否显示在状态栏。
statusBarStyle={"default"}//状态栏样式 default 默认(IOS为白底黑字、Android为黑底白字)
barStyle={"default"}// 状态栏文本的颜色。
/>
<View style={styles.headContent}>
<View style={styles.searchInp}>
<Image style={styles.searchInpIcon} source={require('../../images/search.png')} />
<TextInput
style={styles.TextInput}
returnKeyType={"search"}// 键盘确定按钮类型 done/go/next/search/send
placeholder="请输入要搜索的内容"
placeholderTextColor="#999"
keyboardType="default"
onSubmitEditing={() => {
// 保存搜索内容
this.insertSearch(this.state.searchVal);
// 跳转到搜索结果页,并传搜索内容searchText
navigate("SearchResult", { "searchText": this.state.searchVal })
}}// 确定事件
defaultValue={this.state.searchVal}
onChangeText={(text) => {
this.setState({
searchVal: text
})
}}
autoFocus={true}
/>
</View>
<TouchableOpacity
onPress={() => {
goBack();
}}
activeOpacity={.8}
style={styles.cancleClick}
>
<Text style={styles.cancleBtn}>取消</Text>
</TouchableOpacity>
</View>
<ScrollView>
<View style={styles.searchMain}>
<View style={styles.searchMake}>
<Text style={styles.searchMainTits}>最近搜索</Text>
{/* 删除本地搜索历史按钮 */}
<TouchableOpacity
activeOpacity={0.8}
onPress={() => {
// 判断是否有本地搜索历史
if (this.state.searchHistory.length > 0) {
this.setState({
hasData: true,
})
}
}}
>
<Image source={require('../../images/searchDelete.png')} />
</TouchableOpacity>
</View>
{
this.state.searchHistory.length > 0 ?
<View style={styles.searchMainLabel}>
{this.state.searchHistory.map((item, index) => {
if (index > 9) {
return null
} else {
return (
<TouchableOpacity
onPress={() => {
this.setState({
searchVal: item,
})
// 保存搜索内容
this.insertSearch(item);
navigate("SearchResult", { "searchText": item })
}}
activeOpacity={.8}
style={styles.searchLabelBox}
key={index}>
<Text numberOfLines={1} style={styles.searchLabelText}>{item}</Text>
</TouchableOpacity>
)
}
})
}
</View>
: <View style={styles.noData}>
<Text style={styles.noDataTxt}>暂无搜索历史</Text>
</View>
}
<Text style={styles.searchMainTit}>热门搜索</Text>
<View style={styles.searchMainLabel}>
{/* 热门搜索标签渲染 */}
{this.state.hotTagsArr.map((item, i) => {
return (
<TouchableOpacity
activeOpacity={0.8}
style={styles.searchLabelBox}
key={i}
onPress={() => {
this.setState({
searchVal: item.name,
})
// 保存搜索内容
this.insertSearch(item.name);
navigate("SearchResult", { "label": item })
}}
>
<Text style={styles.searchLabelText}>{item.name}</Text>
</TouchableOpacity>
)
})}
</View>
</View>
</ScrollView>
{/* 删除历史记录确认弹框 */}
<Confirm visible={this.state.hasData}
text="确定删除全部搜索历史吗?"
yesClick={() => {
this.setState({
searchVal: '',
searchHistory: [],
hasData: false,
})
DataBase.removeItem("searchHistory");
}}
noClick={() => {
this.setState({
hasData: false
})
}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.whiteBg,
},
// 头部搜索框
headContent: {
backgroundColor: Colors.white,
paddingTop: StatusBarHeight,
height: NavHeight,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-around',
borderBottomWidth: Pixel,
borderBottomColor: '#ECECEC'
},
searchInp: {
width: Px2dp(304),
height: Px2dp(30),
flexDirection: "row",
alignItems: 'center',
borderRadius: Px2dp(4),
backgroundColor: Colors.grayBg,
marginLeft: Px2dp(16),
},
searchInpIcon: {
width: Px2dp(14),
height: Px2dp(15),
marginLeft: Px2dp(16),
marginRight: Px2dp(8)
},
TextInput: {
flex: 1,
height: Px2dp(30),
fontSize: Px2dp(14),
padding: 0,
},
cancleClick: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
cancleBtn: {
fontSize: Px2dp(14),
color: Colors.text666,
lineHeight: Px2dp(44),
},
// 搜索标签内容盒子
searchMain: {
paddingLeft: Px2dp(16),
paddingRight: Px2dp(16)
},
searchMainTit: {
fontSize: Px2dp(14),
color: Colors.text888,
marginTop: Px2dp(16),
},
searchMainTits: {
fontSize: Px2dp(14),
color: Colors.text888,
},
// 最近搜索
noData: {
height: Px2dp(55),
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginBottom: Px2dp(16)
},
noDataTxt: {
fontSize: Px2dp(15),
color: Colors.text666,
lineHeight: Px2dp(21)
},
searchMake: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
marginTop: Px2dp(16),
},
// 热门搜索
searchMainLabel: {
flexDirection: "row",
flexWrap: 'wrap',
maxHeight: Px2dp(210),
overflow: 'hidden',
},
searchLabelBox: {
borderRadius: Px2dp(2),
backgroundColor: Colors.grayBg,
marginRight: Px2dp(10),
marginTop: Px2dp(10),
height: Px2dp(32),
justifyContent: 'center',
},
searchLabelText: {
fontSize: Px2dp(15),
color: Colors.text666,
paddingLeft: Px2dp(18),
paddingRight: Px2dp(18),
},
});