redux實(shí)踐(一)

上節(jié)我們已經(jīng)完成對(duì)redux和navigation的集成了

下面我們來說明一下redux使用步驟

首先我們來看一張圖


圖片1.png

這里我們了解一下三個(gè)概念 store、action、reducer,store存儲(chǔ)數(shù)據(jù),action,請(qǐng)求狀態(tài)改變動(dòng)作,reducer就是改變狀態(tài)
redux整個(gè)流程原理可以這樣來描述,用戶通過可視化界面View觸發(fā)一個(gè)請(qǐng)求動(dòng)作,在程序內(nèi)部觸發(fā)一個(gè)Action,Action完成數(shù)據(jù)請(qǐng)求和變化工作后,通過reducer來更新state,并寫入store中,整個(gè)流程操作完畢。

下面我們來完成一個(gè)實(shí)例,一個(gè)簡(jiǎn)單獲取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('存儲(chǔ)失敗' + error);
                                // Alert.alert('獲取失敗,請(qǐng)稍后重試');
                            }else {
                                console.log('存儲(chǔ)成功');
                                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
    }
}

這里非常簡(jiǎn)單就是判斷內(nèi)存里面有沒有存儲(chǔ)“userToken”沒有就寫入 ,然后返回token操作。
有了action,就應(yīng)該有有保存action返回的結(jié)果,接下來我們來定義一個(gè)reducer

// Reducer是純函數(shù),里面不應(yīng)該有過多的邏輯。
import { combineReducers  } from 'redux';
// 這個(gè)是ShiTu頁面中用到的Reducer
import ShiTuReducer from './ShiTuReducer';
import StackReducer from './StackReducer';
 
const RootReducer = combineReducers({
    ShiTuReducer,
    StackReducer
});
export default RootReducer;
// ActionTypes里面存放著App中可能發(fā)生的情況
import * as types from '../constant/ActionTypes';

// 初始化值
const initialState = {
    imageURL: 'timg',
    userToken: '',
    webViewUrl: '',
    qiNiuData: null,
};

// 導(dǎo)出ShiTuReducer。
export default function ShiTuReducer(state = initialState, action){
    // console.log(action);

    // 通過switch來判斷types的值,在action中實(shí)現(xiàn)功能
    switch (action.type) {
        // 當(dāng)type=USER_TOKEN_SUCCESS時(shí),會(huì)將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有好多個(gè),那么觸發(fā)保存Action結(jié)果的reducer也必須有多個(gè),那么這里rootReducer相當(dāng)于一個(gè)合成器一樣,把所有reducer合成在一起,而其他reducer就可以各自寫入一個(gè)獨(dú)立的文件中,不相互影響
最后一步,在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(){
    //這個(gè)方法是重置了整個(gè)路由棧信息,那我們要在actions中重新定義路由棧,下面的的index參數(shù)代表新路由棧默認(rèn)顯示的頁面
    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>跳轉(zhuǎn)到ProfileScreen并替換掉main2</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress={()=>{nav.push("Main3")}}>
          <Text>跳轉(zhuǎn)到main3</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

這樣usertoken就能顯示了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容