All Articles

A Simple React Native Redux Example

Working on my latest React Native project, I decided to make the jump from React’s state to Redux.

I looked through all the examples I could find, the majority were from 2015, and couldn’t find something simple and minimal. Also, a lot of things have changed since 2015, and even 2016 - giving me a good excuse to start from scratch. My first step was to go through the Redux docs and tutorials to give myself a clean slate, instead of just copying code from my previous projects.

http://redux.js.org/docs/basics/ExampleTodoList.html

The above link has a minimal example of a Redux implementation, and is what I used as base for my project.

directory structure
This is the directory structure of the app which contains Components, Containers, and Reducers, pretty common with a standard React/Redux app.
example
Simple React Native Redux Example app running in iPhone Simulator.

To show the list of items, I’m using the React Native ListView that is using a Redux Store(items) as its dataSource. There are two actions in the Reducer; ADD_ITEM and REMOVE_ITEM.

// Start the sequence of item ID's at 0
let nextItemId = 0;
// Items reducer
const items = (state = [], action) => {
  switch (action.type) {
    case "ADD_ITEM": {
      return [
        ...state,
        {
          id: nextItemId++,
          name: action.name,
          bgColor: action.bgColor
        }
      ];
    }
    case "REMOVE_ITEM": {
      // Find index of item with matching ID and then
      // remove it from the array by its' index
      const index = state.findIndex(x => x.id === action.id);
      return [...state.slice(0, index), ...state.slice(index + 1)];
    }
    default:
      return state;
  }
};
export default items;

The ListView requires a dataSource, and must be re-rendered when the dataSource is updated. To do this, the dataSource gets mapped to a prop using mapStateToPros, and then we connect the Component to it.

class ItemList extends Component {
  constructor(props) {
    super(props);
    this.handleDestroyItem = this.handleDestroyItem.bind(this);
  }
handleDestroyItem(id) {
    this.props.dispatch({ type: "REMOVE_ITEM", id });
  }
render() {
    return (
      <ListView
        style={styles.container}
        enableEmptySections={true}
        dataSource={this.props.dataSource}
        renderRow={rowData => {
          return (
            <Item
              rowData={rowData}
              handleDestroyItem={id => this.handleDestroyItem(id)}
            />
          );
        }}
      />
    );
  }
}
// Handle data source change from redux store
const dataSource = new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2
});
function mapStateToProps(state) {
  return {
    dataSource: dataSource.cloneWithRows(state.items)
  };
}
ItemList.propTypes = {
  dataSource: PropTypes.object,
  dispatch: PropTypes.func
};
export default connect(mapStateToProps)(ItemList);

View the entire code at https://github.com/aaronvb/react-native-redux-example.