2016-11-20 16 views
1

我是redux的新手,所以試圖找出一個認證用例的簡單示例。此代碼的Web版本從localstorage獲取初始狀態,並設置爲localstorage。將此示例轉換爲react-native意味着localstorage更改爲異步的AsyncStorage並返回承諾。如何處理reducer中的異步承諾

如何處理reducer中的異步初始值設定項?

import { AsyncStorage } from 'react-native'; 
import { 
    LOGIN_REQUEST, LOGIN_SUCCESS, LOGIN_FAILURE, LOGOUT_SUCCESS, 
} from '../actions/login'; 


const initialState = { 
    isFetching: false, 
    token: null, // AsyncStorage.getItem('token'), 
    profile: null, // AsyncStorage.getItem('profile'), 
    isLoggedIn: false, 
    errorMessage: null, 
}; 

// The auth reducer. The starting state sets authentication 
// based on a token in asyncstorage. In addition we would also null 
// the token if we check that it's expired 
export default (state = initialState, action) => { 
    switch (action.type) { 
    case LOGIN_REQUEST: 
     return Object.assign({}, state, { 
     isFetching: true, 
     isLoggedIn: false, 
     token: null, 
     user: null, 
     errorMessage: '', 
     }); 
    case LOGIN_SUCCESS: 
     // todo set the async 
     // AsyncStorage.multiSet(['token', 'profile'], [action.token, action.profile]) 
     return Object.assign({}, state, { 
     isFetching: false, 
     isLoggedIn: true, 
     token: action.token, 
     user: action.profile, 
     errorMessage: '', 
     }); 
    case LOGIN_FAILURE: 
     return Object.assign({}, state, { 
     isFetching: false, 
     isLoggedIn: false, 
     token: null, 
     errorMessage: action.message, 
     }); 
    case LOGOUT_SUCCESS: 
     // AsyncStorage.multiRemove(['token', 'profile']) 
     return Object.assign({}, state, { 
     isFetching: true, 
     isLoggedIn: false, 
     token: null, 
     }); 
    default: 
     return state; 
    } 
}; 

回答

1

從AsyncStorage獲取初始數據創建動作創建者。當您的應用程序加載時(可以在您的根組件的componentDidMount中執行此操作),使用鍵調度動作爲tokenprofile

// create similar actions creators for 'setItem' and 'multiSet' ops 
export function loadLocalData(key) { 
    return { 
    types: [LOAD_LOCAL_DATA, LOAD_LOCAL_DATA_SUCCESS, LOAD_LOCAL_DATA_FAIL] 
    asyncStoragePromise:() => AsyncStorage.getItem(key), 
    key, 
    } 
} 

現在創建AsyncStorage操作的middleware。確保您在創建storeapplyMiddleware

最常見的使用情況下,中間件是支持對庫 喜歡的Rx異步 動作沒有太多的樣板代碼或依賴。它通過讓您將異步操作加入 來執行正常操作。

export default function asyncStorageMiddleware() { 
    return ({ dispatch, getState }) => next => (action) => { 
    if (typeof action === 'function') { 
     return action(dispatch, getState); 
    } 

    const { asyncStoragePromise, types, ...rest } = action; 

    if (!asyncStoragePromise) { 
     return next(action); 
    } 

    const [REQUEST, SUCCESS, FAILURE] = types; 

    next({ ...rest, type: REQUEST }); 

    const actionPromise = asyncStoragePromise(); 
    actionPromise 
     .then(result => next({ ...rest, result, type: SUCCESS })) 
     .catch(error => next({ ...rest, error, type: FAILURE })); 

    return actionPromise; 
    }; 
} 

終於在這裏是你的初始化狀態

const initialState = { 
    isFetching: false, 
    token: null, 
    profile: null, 
    isLoggedIn: false, 
    errorMessage: null, 
    localLoadErr: '', 
}; 

減速

LOAD_LOCAL_DATA_SUCCESS: 
    return { 
    ...state, 
    [action.key]: action.result, 
    }; 
    break; 

LOAD_LOCAL_DATA_FAIL: 
    return { 
    ...state, 
    localLoadErr: action.error, 
    }; 
    break;