美文网首页
redux实践(一)

redux实践(一)

作者: 木中木 | 来源:发表于2017-08-26 15:18 被阅读0次

    上节我们已经完成对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就能显示了

    相关文章

      网友评论

          本文标题:redux实践(一)

          本文链接:https://www.haomeiwen.com/subject/vunmdxtx.html