Basic Redux Counter Example

This is a simple single page application that uses Redux and NativeBase as the main Libraries.

Find full code here


ReduxCounter Example

1. Aim

We aim to create a simple App that has a counter with increment and decrement functionality. The logic is implemented in Redux.

2. Installation

Note:
If you encounter an issue with React Native Router Flux during building your project, it might be due to issue with latest versions of React Native. Check out this issue. You might have to bump down the versions of React Native and React

  1. SetUp React Native Project
    SetUp a React Native project. Refer this for more information about setting up a React Native project.

  2. Installing Libraries
    With a React Native project SetUp, We can now install all required Libraries as follows.

    a. Redux and react-redux
    In your terminal enter the following
    npm install redux react-redux --save

    b. NativeBase
    npm install native-base@2 --save

    c. Configure dependencies
    react-native link

    By the end of Installation, your package.json file should look something like this.

Redux Counter

3. Setting Things Up

With all required Libraries installed, we can start with some real coding. In the root of your project create a folder src. Inside this folder we create three folders namely reducers, actions, components and one file App.js.

3.1. Redux Store Setup

We need to create our store inside our App.js file. If you are unfamiliar with basic Redux concepts, refer this Documentation.

App.js Code

import React, { Component } from 'react';
import allReducers from './reducers/index.js';
import {createStore} from 'redux';
import {Provider} from 'react-redux';
import Counter from './components/counter.js';
const store = createStore(allReducers);
export default class App extends Component{
  render(){
    return(
      <Provider store= {store}>
        <Counter />
      </Provider>
    );
  }
}
  • We are optimistic here while importing allReducers from reducers folder.
  • createStore function takes in our allReducers object and creates our Store.
  • Provider component makes the store available throughout our App.

3.2. Redux Reducers Setup

Reducers will return the data needed by our app. Here we simply need a reducer to return the Counter value.
Create a file countReducer.js inside reducers folder.

Code reducers/countReducer.js

let count= 0;
export default function(state=count, action){
  switch (action.type) {
    case "Increment": count++;
      break;
    case "Decrement": count--;
      break;
  }
  return count;
}

The reducer defined above will return the always return count value. Increment and Decrement action types will manipulate the count value as shown.
We combine all reducers inside index.js file inside reducers function.

Code reducers/index.js

import {combineReducers} from 'redux';
import countReducer from './countReducer.js';
const allReducers= combineReducers({
  count: countReducer,
});
export default allReducers;

3.3. Redux Actions Setup

We will simply create two actions Increment and Decrement.

Code actions/index.js

export function increment(){
  return{
    type: "Increment"
  };
}
export function decrement(){
  return{
    type: "Decrement"
  };
}

3.4. Redux Component Setup

We just need one component here. A counter component.

3.5. Important stuff

In order to be able to use Reducers and actions, we need to use two important functions. Both these functions have extremely simple applications (although the names sound scary enough).

  • mapStateToProps => This function, simply takes your reducer data, that is required, and converts it into a usable Prop. Now we can use the data as a prop. example this.props.data.

General Syntax of mapStateToProps

function mapStateToProps(state){
  return{
    dataObj : state.reducerName
  };
}

Note: Remember how we allotted names to Reducers in the combineReducers function. We use the same name to call respective Reducer.

  • matchDispatchToProps => This function simply converts our Actions into usable props.
    General Syntax of matchDispatchToProps
function matchDispatchToProps(dispatch){
  return bindActionCreators({action1: importedAction1, action2: importedAction2}, dispatch)
}
 

Note: bindActionCreators function here simply combines our actions into a single object.

Code components/counter.js

import React, { Component } from 'react';
import { Container, Content, Text, Card, Header, Body, Button, Title, CardItem } from 'native-base';
import { increment, decrement } from '../actions/index.js';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
class Counter extends Component{
  render(){
    console.log(this.props.count);
    return(
      <Container>
        <Header>
          <Body>
            <Title>Redux Counter</Title>
          </Body>
        </Header>
        <Content padder>
          <Card>
            <CardItem>
              <Text>
                {this.props.count}
              </Text>
            </CardItem>
          </Card>
          <Button dark bordered onPress= {() => this.props.increment()}>
            <Text>Increment</Text>
          </Button>
          <Button dark bordered onPress= {() => this.props.decrement()}>
            <Text>Decrement</Text>
          </Button>
        </Content>
      </Container>
    );
  }
}
function mapStateToProps(state){
  return{
    count : state.count
  };
}
function matchDispatchToProps(dispatch){
  return bindActionCreators({increment: increment, decrement: decrement}, dispatch)
}
export default connect(mapStateToProps, matchDispatchToProps)(Counter);

3.6. Finishing up

Lastly we import our App in our index.js file.

Code index.js

import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import App from './src/App.js';
export default class ReduxCounter extends Component {
  render() {
    return (
      <App />
    );
  }
}
AppRegistry.registerComponent('ReduxCounter', () => ReduxCounter);

results matching ""

    No results matching ""