上节我们已经完成对redux和navigation的集成了
下面我们来说明一下redux使用步骤
首先我们来看一张图
图片1.png
这里我们了解一下三个概念 store、action、reducer,store存储数据,action,请求状态改变动作,reducer就是改变状态
redux整个流程原理可以这样来描述,用户通过可视化界面View触发一个请求动作,在程序内部触发一个Action,Action完成数据请求和变化工作后,通过reducer来更新state,并写入store中,整个流程操作完毕。
下面我们来完成一个实例,一个简单获取token的过程
1.定义获取token的Action
let KEY = 'USERTOKEN';
export function userToken() {
return dispatch => {
return AsyncStorage.getItem(KEY,(Error,result)=>{
if (result === null){
let data = JSON.parse('{"success":true,"token":"e143e928-032c-47ea-a571-f49bcaf83842"}');
if (data && data.success){
let token = data.token;
AsyncStorage.setItem(KEY,token,(error)=>{
if (error){
console.log('存储失败' + error);
// Alert.alert('获取失败,请稍后重试');
}else {
console.log('存储成功');
dispatch(getUserToken(token));
}
})
}
}else {
console.log('获取成功' + result);
// TOKEN = '0ddc64eb-48e3-4d4c-a83c-a61caa2450d4';
dispatch(getUserToken(result));
}
});
}
};
export function getUserToken(userToken) {
return {
type: types.USER_TOKEN_SUCCESS,
userToken
}
}
这里非常简单就是判断内存里面有没有存储“userToken”没有就写入 ,然后返回token操作。
有了action,就应该有有保存action返回的结果,接下来我们来定义一个reducer
// Reducer是纯函数,里面不应该有过多的逻辑。
import { combineReducers } from 'redux';
// 这个是ShiTu页面中用到的Reducer
import ShiTuReducer from './ShiTuReducer';
import StackReducer from './StackReducer';
const RootReducer = combineReducers({
ShiTuReducer,
StackReducer
});
export default RootReducer;
// ActionTypes里面存放着App中可能发生的情况
import * as types from '../constant/ActionTypes';
// 初始化值
const initialState = {
imageURL: 'timg',
userToken: '',
webViewUrl: '',
qiNiuData: null,
};
// 导出ShiTuReducer。
export default function ShiTuReducer(state = initialState, action){
// console.log(action);
// 通过switch来判断types的值,在action中实现功能
switch (action.type) {
// 当type=USER_TOKEN_SUCCESS时,会将action中的值,
// 赋给userToken,在ShiTu.js中就能拿到userToken的值。
case types.USER_TOKEN_SUCCESS:
// console.log(action);
return Object.assign({}, state, {
...state,
userToken: action.userToken,
});
case types.QINIU_UPLOAD_TOKEN:
// console.log(action);
return Object.assign({}, state, {
qiNiuData:action.qiNiuData,
});
case types.WEBVIEW_URL:
return Object.assign({}, state ,{
...state,
webViewUrl:action.webViewUrl,
});
case types.BACKIMAGE_URL:
return Object.assign({}, state ,{
imageURL:action.imageURL,
});
default:
return state;
}
}
import { MyApp } from '../App';
export default function StackReducer(state , action) {
let nextState = MyApp.router.getStateForAction(action, state);
return nextState || state;
}
以上三段代码解释一下,我们知道Action有好多个,那么触发保存Action结果的reducer也必须有多个,那么这里rootReducer相当于一个合成器一样,把所有reducer合成在一起,而其他reducer就可以各自写入一个独立的文件中,不相互影响
最后一步,在Main2中如何使用呢?
export default connect((state) => {
const { ShiTuReducer ,StackReducer } = state;
return {
ShiTuReducer,
StackReducer
};
},{ userToken })(Main2);
class Main2 extends Component {
constructor(props){
super(props);
this.state = {
userName:'linjian',
userToken:'',
}
this.resetActions = this.resetActions.bind(this);
this.goBack = this.goBack.bind(this)
}
componentDidMount(){
// 使用userToken方法。
this.props.userToken();
}
componentWillReceiveProps(nextProps){
const { userToken} = nextProps.ShiTuReducer;
this.setState({userToken:userToken});
}
resetActions(){
//这个方法是重置了整个路由栈信息,那我们要在actions中重新定义路由栈,下面的的index参数代表新路由栈默认显示的页面
const resetAction = NavigationActions.reset({
index: 1,
actions: [
NavigationActions.navigate({ routeName: 'ReactNavigation'}),
NavigationActions.navigate({ routeName: 'profile'})
]
})
this.props.navigation.dispatch(resetAction)
}
goBack(){
// debugger;
let routes = this.props.StackReducer.routes;
routes.forEach(function(item) {
if(item.routeName === 'Main2'){
const { goBack } = this.props.navigation;
goBack(item.key);
}
}, this);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to Main22222!
</Text>
<Text style={styles.instructions}>
The user toke is {this.state.userToken}
</Text>
<Text style={styles.instructions}>
Double tap R on your keyboard to reload,{'\n'}
Shake or press menu button for dev menu
</Text>
<Text style={styles.instructions}>
userName:{this.state.userName}
</Text>
<TouchableOpacity onPress={()=>{this.resetActions()}}>
<Text>跳转到ProfileScreen并替换掉main2</Text>
</TouchableOpacity>
<TouchableOpacity onPress={()=>{nav.push("Main3")}}>
<Text>跳转到main3</Text>
</TouchableOpacity>
</View>
);
}
}
这样usertoken就能显示了
网友评论