React-Native实战二(清理app缓存+Redux )
来源:互联网 发布:传奇霸业龙脉升级数据 编辑:程序博客网 时间:2024/05/21 11:01
前言:前面做了一下rn的清理app缓存功能,下面把前面说的rn中处理页面与页面之间的数据传递问题解决一下,在解决之前,我们先来认识一下什么是redux。
先附上redux的官方demo地址:https://github.com/alinz/example-react-native-redux#counter-example
1、什么是redux?
redux是一个用于管理js应用状态的容器。redux出现时间并不是很长,在它出现之前也有类似功能的模块出现,诸如flux等等。redux设计的理念很简单,似乎最初这个开发团队就有让redux可以方便融入在server, browser, mobile client端的打算。目前在github上redux-*的第三方中间件、插件越来越多。如果react项目中想使用redux,那么就有react-redux插件来完成配合。
2、为什么要用redux?
搞过React Native的都知道,rn中更新组件主要通过改变state从而更新组件。
先盗用一张网络上的rn生命周期图:
当我们改变state的时候,rn会重新走一遍render方法,从而更新组件,但是在rn中,每个页面都管理者自己的state,如果需要一个页面管理另外一个页面的state,那么我们就有点无从下手了,但是redux很巧妙的帮我们管理着所有的state。
redux提供了一套机制来组织管理整个应用状态。
Redux有三部分组成:store,action,reducer。
store:维护全局的state,以及将action和reducer结合起来。
action:用来传递state的信息。(比如:我们在action中处理登陆操作,将返回的user对象传递给对应的reducer.)
reducer:reducer是简单的处理函数,通过传入旧的state和指示操作的action来更新state,从而达到页面的刷新。
上图是redux状态改变的流程。action -> reducer -> 新store -> 反馈到UI上有所改变。
直白一点就是:用户发送点击清理缓存按钮(action)
—>
reducer接受到用户发送的action,并且接收到action中携带了(缓存大小、是否清理完毕等信息)
—>
reducer返回一个新的state(是否清理成功)
—>
state返回到全局变量store中
—>
回调用户页面方法,重新走render方法—>更新页面的值。
下面结合我们前面的清理缓存的例子来集成下redux:
首先安装相关库(进入项目的根目录执行下面命令):
安装redux: npm install –save redux
安装redux绑定库: npm install –save React-redux
安装开发者工具: npm install –save-dev redux-devtools
安装异步action构造器: npm install –save redux-thunk
包都很小,想必大家很快就实现了!!
第一步:创建store
///创建redux 的 storeimport reducers from '../Redux/reducers';import { Provider } from 'react-redux';import { createStore, applyMiddleware} from 'redux';import thunk from 'redux-thunk';//引入异步操作const middlewares = [thunk];const createSoreWithMiddleware = applyMiddleware(...middlewares)(createStore);class Main extends Component { // 构造 constructor(props) { super(props); // 初始状态 this.state = { store:createSoreWithMiddleware(reducers) }; } render() { //创建store return ( <Provider store={this.state.store}> <Main2/> </Provider> ); };}module.exports = Main;
以上是我的app主入口,Main2是我们的app主页面,也就是前面的那张截图。
我们需要把所有的reducer加载到store中,reducer就是用来处理返回给用户state的东西,
一般会创建一下index.js文件来统一管理所有的reduce文件:
import clear from './clear';import {combineReducers} from 'redux'let MainReducers = combineReducers({ clear})module.exports = MainReducers;
我们需要建一个叫clear的reducer文件:
import * as types from '../actions/actionTypes';const initialState = { size: '0.00M'};export default function clear(state = initialState, action = {}) { switch (action.type) { case types.CLEAR_CACHE: return { ...state, size:action.size }; default: return state; }}
因为获取缓存大小都在action中处理了,然后我们直接返回state为action中的size。
对应的action:
import * as types from './actionTypes';var CacheManager = require('react-native-http-cache');export function clearCache() { return dispatch=> { let result = CacheManager.getCacheSize().then((value)=> { dispatch({type: types.CLEAR_CACHE, size: Math.round((value / 1024 / 1024) * 100) / 100 + 'M'}); }, (erro)=> { dispatch({type: types.CLEAR_CACHE, size: '0M'}); }); }}
这里说一下dispatch,说dispatch之前,先说一下store对象中的一些方法:
dispatch用来发送一个action,getstate用来获取state,subscribe用来注册回调函数。
我们在action中用到了dispatch来返回我们的操作:
return dispatch=> { let result = CacheManager.getCacheSize().then((value)=> { dispatch({type: types.CLEAR_CACHE, size: Math.round((value / 1024 / 1024) * 100) / 100 + 'M'}); }, (erro)=> { dispatch({type: types.CLEAR_CACHE, size: '0M'}); });
因为getCacheSize获取值是异步的操作,所以我们不能直接返回一个action对象,我们通过拿到value 后又发送一个action(并且把获取到的value封装进action)的方法发送给store,然后给reducer,最后返回给用户界面。
第二步:关联页面跟store
在我们的Main2(主页面中建立与store的关联关系)
/** * 主体框架类 */import React, { Component } from 'react';import { AppRegistry, StyleSheet, Text, View, Image, Platform, Navigator, StatusBar} from 'react-native';/** * 导入外部组件类 */import TabNavigator from 'react-native-tab-navigator';var Home = require('../Home/YQYHome');var Mine = require('../Mine/YQYMine');var More = require('../More/YQYMore');var Store = require('../Store/YQYStore');var ScreenUtils = require('../ScreenUtils');let colors = ['11', '22'];//连接各个组件import {bindActionCreators} from 'redux';import * as counterActions from '../Redux/actions/counterActions';import { connect } from 'react-redux';var MiXin = require('react-timer-mixin');class Main2 extends Component { // 构造 constructor(props) { super(props); // 初始状态 this.state = { selectedTab: 'home'//默认第一个home页 }; } render() { console.log('renderMain2'); return ( <TabNavigator> {/*--首页--*/} {this._renderItem('首页', 'icon_tabbar_homepage', 'icon_tabbar_homepage_selected', 'home', Home)} {/*--商家--*/} {this._renderItem('商家', 'icon_tabbar_merchant_normal', 'icon_tabbar_merchant_selected', 'shop', Store)} {/*--我的--*/} {this._renderItem('我的', 'icon_tabbar_mine', 'icon_tabbar_mine_selected', 'mine', Mine)} {/*--更多--*/} {this._renderItem('更多', 'icon_tabbar_misc', 'icon_tabbar_misc_selected', 'more', More)} </TabNavigator> ); } /** * 渲染item * @param title * @param iconUri * @param selectedIconUri * @param selectedTab * @param component * @returns {XML} * @private */ _renderItem(title, iconUri, selectedIconUri, selectedTab, component, badge) { let self = this; const { state, actions } = self.props; return ( <TabNavigator.Item title={title} renderIcon={() => <Image source={{uri:iconUri}} style={styles.iconStyle} resizeMode='stretch'/>} renderSelectedIcon={() => <Image source={{uri:selectedIconUri}} style={styles.iconStyle} resizeMode='stretch'/> } onPress={()=>{ this.setState({ selectedTab:selectedTab }); if(selectedTab==='more'&&actions.clearCache){ MiXin.setTimeout(()=>{ actions.clearCache(); },500); } }} selected={this.state.selectedTab===selectedTab} badgeText={badge} selectedTitleStyle={styles.selectedTitleStyle} titleStyle={{ fontSize:ScreenUtils.setSpText(10), color:'#333333' }} tabStyle={{ alignItems:'center', marginBottom:6 }} > <Navigator initialRoute={{name:title,component:component}} configureScene={()=>{ return Navigator.SceneConfigs.PushFromRight }} renderScene={(route,navigator)=>{ let Component=route.component; return ( <View style={{flex:1}}> <StatusBar translucent={true} barStyle={'light-content'} backgroundColor='transparent' > </StatusBar> <Component {...actions} size={state.size} navigator={navigator} /> </View> ) }} /> </TabNavigator.Item> ); }}const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: ScreenUtils.scaleSize2(5), }, iconStyle: { width: ScreenUtils.scaleSize2(40), height: ScreenUtils.scaleSize2(40), }, selectedTitleStyle: { color: 'orange' }});//关联当前页面与store,通过props的方式传给组件export default connect(state => ({ state: state.clear }), (dispatch) => ({ actions: bindActionCreators(counterActions, dispatch) }))(Main2);
此时页面中的props拥有store中特定的state跟actions,于是我们可以很容易的发送一个action跟获取发送action之后 ruducer返回给我的state:
render() { console.log('renderMore'); let{size,clearCache}=this.props; {/*---清空缓存----*/} <CommCell title='清空缓存' onItemClick={()=>{ this._clearCache(); } } desc={size} /> }
用过TabNavigator的童鞋都知道,当我们第一次进入app的时候加载了四个view,以后就不会加载了,但是我们需要当点击more页面的时候,每次都要重新获取一下缓存的大小,所以我们要在我们放在主页面的TabNavigator做下处理了,当点击的item为more的时候,发送一个action最后更新more中的内容。。
<TabNavigator.Item title={title} renderIcon={() => <Image source={{uri:iconUri}} style={styles.iconStyle} resizeMode='stretch'/>} renderSelectedIcon={() => <Image source={{uri:selectedIconUri}} style={styles.iconStyle} resizeMode='stretch'/> } onPress={()=>{ this.setState({ selectedTab:selectedTab }); if(selectedTab==='more'&&actions.clearCache){ MiXin.setTimeout(()=>{ actions.clearCache(); },500); } }}
我们可以看到,有了redux,我们很容易的管理了所有的state,从而达到了通信的目的。但是redux的作者也不建议大家在不满足redux的条件下使用redux。
从组件角度看,如果你的应用有以下场景,可以考虑使用 Redux。
某个组件的状态,需要共享
某个状态需要在任何地方都可以拿到
一个组件需要改变全局状态
一个组件需要改变另一个组件的状态
当然,主要是我是结合我的项目讲的,可能理解起来比较吃力哈,
大家也可以看一下阮大神的博客:
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
最后祝大家早日成为大神哈!!!!一起努力,(ps:有需要资料的可以加群私聊我哈,不谢!!)
- React-Native实战二(清理app缓存+Redux )
- React-Native实战之(清理app缓存+Redux合成)
- React-Native实战之(清理app缓存+Redux合成)
- React-Native 开发(二) 在react-native 中 运用 redux
- redux在react-native上使用(二)--加入redux-saga
- React Native 实战系列二
- react native redux
- react native redux counter
- react-native redux debug
- React Native集成Redux
- React Native 之 Redux
- react native and redux
- react-native redux学习心得
- react-native + redux 实践
- React Native 集成 Redux
- React-Native+typescript+redux写糗事百科app
- React-Native 之 redux 与 react-redux
- React-Native 之 redux 与 react-redux
- 回顾我的2016年
- 随机生成个人信息
- ant style介绍和在spring中的应用
- MySql5.7安装过程
- Android Studio Error: No sdk api is defined in local.properties
- React-Native实战二(清理app缓存+Redux )
- 从输入网址到浏览器显示页面发生了什么
- spark core 2.0 SerializedShuffleHandle UnsafeShuffleWriter ShuffleExternalSorter
- 使用 @SuppressWarnings 来排除警告(@SuppressWarning を使用しての警告の排除)
- Linux 安装完Ubuntu Linux后如何修改root用户密码
- LitePal数据库
- MySQL之GTID主从同步
- 什么是SOLID
- struts 访问servlet api (Servlet...Aware方式)