Skip to content

Instantly share code, notes, and snippets.

@spencercarli
Created December 6, 2016 01:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save spencercarli/6af2fb18cb20c992072d7bc7ef94eefc to your computer and use it in GitHub Desktop.
Save spencercarli/6af2fb18cb20c992072d7bc7ef94eefc to your computer and use it in GitHub Desktop.
Basic Setup
// app/actions.js
export const requestPerson = ({ index = 1 }) => {
return (dispatch) => {
dispatch({ type: 'INC_PERSON_INDEX' });
fetch(`https://swapi.co/api/people/${index}?format=json`)
.then((res) => res.json())
.then((res) => {
dispatch({ type: 'SAVE_PERSON', person: res });
})
};
};
// index.ios.js
import { AppRegistry } from 'react-native';
import App from './app';
AppRegistry.registerComponent('OfflineActions', () => App);
// index.ios.js
import { AppRegistry } from 'react-native';
import App from './app';
AppRegistry.registerComponent('OfflineActions', () => App);
// app/index.js
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import configureStore from './store';
import NameList from './NameList';
class App extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
store: configureStore(() => this.setState({ isLoading: false })),
};
}
render() {
if (this.state.isLoading) return null;
return (
<Provider store={this.state.store}>
<NameList />
</Provider>
);
}
}
export default App;
// app/NameList.js
import React, { Component } from 'react';
import { View, Text, ScrollView } from 'react-native';
import { List, ListItem, Icon } from 'react-native-elements'
import { connect } from 'react-redux';
import { requestPerson } from './actions';
class NameList extends Component {
render() {
return (
<View style={{ flex: 1 }}>
<ScrollView>
<List>
{
this.props.people.map((item, i) => (
<ListItem
key={i}
title={item.name}
/>
))
}
</List>
</ScrollView>
<Icon
raised
name='add'
color='#51b9d3'
reverse
onPress={() => this.props.dispatch(requestPerson({ index: this.props.personIndex }))}
containerStyle={{ position: 'absolute', right: 20, bottom: 20 }}
/>
</View>
);
}
}
const mapStateToProps = (state) => {
return {
people: state.people,
personIndex: state.personIndex,
};
};
export default connect(mapStateToProps)(NameList);
// app/reducer.js
const initialState = {
personIndex: 1,
people: [],
actionQueue: [],
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'INC_PERSON_INDEX':
return Object.assign({}, state, {
personIndex: state.personIndex + 1,
});
case 'SAVE_PERSON':
return Object.assign({}, state, {
people: [action.person].concat(state.people),
});
case 'ADD_TO_ACTION_QUEUE':
return Object.assign({}, state, {
actionQueue: state.actionQueue.concat([action.payload]),
});
default:
return state
}
}
export default reducer;
// app/store.js
import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import thunk from 'redux-thunk';
import reducer from './reducer';
const middleWare = [thunk];
const createStoreWithMiddleware = applyMiddleware(...middleWare)(createStore);
export default configureStore = (onComplete) => {
const store = autoRehydrate()(createStoreWithMiddleware)(reducer);
persistStore(store, { storage: AsyncStorage }, onComplete);
return store;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment