Add basic redux setup
This commit is contained in:
parent
eccbdf4a79
commit
fbbc8bd814
9 changed files with 142 additions and 18 deletions
29
app/actions/buildAsyncAction.js
Normal file
29
app/actions/buildAsyncAction.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { CALL_API } from 'redux-api-middleware';
|
||||
import _ from 'underscore';
|
||||
|
||||
export default function buildRsaAction(actionSet, path, method, optionalData, meta) {
|
||||
|
||||
const types = _.map([actionSet.REQUEST, actionSet.SUCCESS, actionSet.FAILURE], (requestType) => {
|
||||
if (meta) {
|
||||
return { type: requestType, meta: _.clone(meta) };
|
||||
}
|
||||
return { type: requestType };
|
||||
});
|
||||
|
||||
let actionData = {
|
||||
types: types,
|
||||
endpoint: path,
|
||||
method,
|
||||
headers: {
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
};
|
||||
if (optionalData && !_.isEmpty(optionalData)) {
|
||||
actionData.headers['Content-Type'] = 'application/json';
|
||||
actionData.body = JSON.stringify(optionalData);
|
||||
}
|
||||
|
||||
return {
|
||||
[CALL_API]: actionData
|
||||
};
|
||||
}
|
16
app/actions/index.js
Normal file
16
app/actions/index.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import methods from './methods';
|
||||
import makeAsyncActionSet from './makeAsyncActionSet';
|
||||
import buildAsyncAction from './buildAsyncAction';
|
||||
import endpoints from '../settings/endpoints';
|
||||
|
||||
|
||||
export const LOGIN = makeAsyncActionSet('LOGIN');
|
||||
export function login(token) {
|
||||
return buildAsyncAction(
|
||||
LOGIN,
|
||||
endpoints.get('USER_INFO').query({ 'circle-token': token }).toString(),
|
||||
methods.GET,
|
||||
{},
|
||||
{ token }
|
||||
);
|
||||
}
|
7
app/actions/makeAsyncActionSet.js
Normal file
7
app/actions/makeAsyncActionSet.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default function makeAsyncActionSet(actionName) {
|
||||
return {
|
||||
REQUEST: actionName + '_REQUEST',
|
||||
SUCCESS: actionName + '_SUCCESS',
|
||||
FAILURE: actionName + '_FAILURE'
|
||||
};
|
||||
}
|
6
app/actions/methods.js
Normal file
6
app/actions/methods.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
export default {
|
||||
GET: 'GET',
|
||||
PATCH: 'PATCH',
|
||||
POST: 'POST',
|
||||
PUT: 'PUT'
|
||||
};
|
|
@ -5,6 +5,9 @@ import RouteMapper from './components/navigation/RouteMapper';
|
|||
import GlobalStyles from './settings/styles';
|
||||
import BusyIndicator from 'react-native-busy-indicator';
|
||||
|
||||
import { Provider } from 'react-redux';
|
||||
import configureStore from './store';
|
||||
|
||||
require('moment-duration-format');
|
||||
|
||||
const {
|
||||
|
@ -26,7 +29,9 @@ const styles = StyleSheet.create({
|
|||
}
|
||||
});
|
||||
|
||||
export default class extends React.Component {
|
||||
const store = configureStore();
|
||||
|
||||
export default class App extends React.Component {
|
||||
renderScene(route, nav) {
|
||||
const Component = route.component;
|
||||
const props = route.props || {};
|
||||
|
@ -46,6 +51,7 @@ export default class extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<Navigator
|
||||
renderScene={this.renderScene}
|
||||
|
@ -64,6 +70,7 @@ export default class extends React.Component {
|
|||
/>
|
||||
<BusyIndicator />
|
||||
</View>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
9
app/reducers/index.js
Normal file
9
app/reducers/index.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { combineReducers } from 'redux';
|
||||
import * as storage from 'redux-storage';
|
||||
|
||||
import user from './user';
|
||||
|
||||
|
||||
export default storage.reducer(combineReducers({
|
||||
user
|
||||
}));
|
11
app/reducers/user.js
Normal file
11
app/reducers/user.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import * as actions from '../actions';
|
||||
import { Map } from 'immutable';
|
||||
|
||||
export default function user(state = Map(), action) {
|
||||
console.log(action.type);
|
||||
if (action.type === actions.LOGIN.SUCCESS) {
|
||||
console.log('SUCCESS!', action.meta.token);
|
||||
return Map(action.payload).set('token', action.meta.token);
|
||||
}
|
||||
return state;
|
||||
}
|
35
app/store.js
Normal file
35
app/store.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { createStore, applyMiddleware } from 'redux';
|
||||
import reducers from './reducers';
|
||||
|
||||
import settings from './settings/constants';
|
||||
import * as storage from 'redux-storage';
|
||||
import createEngine from 'redux-storage-engine-reactnativeasyncstorage';
|
||||
import filter from 'redux-storage-decorator-filter';
|
||||
|
||||
import { apiMiddleware } from 'redux-api-middleware';
|
||||
|
||||
const engine = filter(createEngine(settings.get('STORAGE_KEY')));
|
||||
|
||||
const storeMiddleware = storage.createMiddleware(engine);
|
||||
|
||||
|
||||
export default function configureStore(initialState) {
|
||||
const load = storage.createLoader(engine);
|
||||
|
||||
const createStoreWithMiddleware = applyMiddleware(
|
||||
apiMiddleware,
|
||||
storeMiddleware // Last in list
|
||||
)(createStore);
|
||||
|
||||
const store = createStoreWithMiddleware(reducers);
|
||||
|
||||
load(store)
|
||||
.then(function (newData) {
|
||||
console.log('LOADED STATE');
|
||||
})
|
||||
.catch(function () {
|
||||
console.log('FAILED TO LOAD STATE', arguments);
|
||||
});
|
||||
|
||||
return store;
|
||||
}
|
|
@ -22,6 +22,10 @@
|
|||
"react-redux": "=3.1.2",
|
||||
"redux": "=3.0.5",
|
||||
"redux-api-middleware": "git://github.com/realorangeone/redux-api-middleware#4edf49b04fe459cc69c8ccd758180d3a6d66bf2e",
|
||||
"redux-storage": "=4.0.0",
|
||||
"redux-storage-decorator-filter": "=1.1.3",
|
||||
"redux-storage-engine-reactnativeasyncstorage": "=1.0.0",
|
||||
"redux-storage-merger-immutablejs": "=1.0.1",
|
||||
"underscore": "=1.8.3",
|
||||
"url": "=0.11.0",
|
||||
"url-assembler": "=1.2.4"
|
||||
|
|
Reference in a new issue