Redux – AppDividend https://appdividend.com Latest Code Tutorials Wed, 20 Mar 2019 19:43:10 +0000 en-US hourly 1 https://wordpress.org/?v=5.1.1 https://appdividend.com/wp-content/uploads/2017/08/cropped-ApDivi-32x32.png Redux – AppDividend https://appdividend.com 32 32 Redux Thunk Tutorial With Example From Scratch https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/ https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/#comments Wed, 03 Oct 2018 20:04:29 +0000 http://localhost/wordpress/?p=1826 Getting Started With redux-thunk

In this example, we will see Redux Thunk Tutorial With Example From Scratch. Redux is a predictable container state management system. It’s a lightweight implementation of Flux, which is another library for managing the state. Redux allows us to put a middleware that sits between an action being dispatched and the action that reaching to the reducers. Two very […]

The post Redux Thunk Tutorial With Example From Scratch appeared first on AppDividend.

]]>
Getting Started With redux-thunk

In this example, we will see Redux Thunk Tutorial With Example From Scratch. Redux is a predictable container state management system. It’s a lightweight implementation of Flux, which is another library for managing the state. Redux allows us to put a middleware that sits between an action being dispatched and the action that reaching to the reducers. Two very popular middleware libraries that will allow for side effects and asynchronous activities are Redux Thunk and Redux Saga. Redux Thunk is the middleware that lets you call the action creators that return a function instead of the action object. That function then receives the store’s dispatch method, which is then used to dispatch the regular synchronous actions inside a body of the function once the asynchronous operations have completed.  The thunk is a concept in programming where a function is used to delay the evaluation/calculation of an operation.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.
Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Join the program

Redux Thunk Tutorial With Example From Scratch

Let us install React.js using the following command.

#1: Install React.js

npx create-react-app reactreduxthunk

 

Redux Thunk Tutorial With Example From Scratch

#2: Install Redux, react-redux, and redux-thunk.

Go inside the folder and type the following command to install the axiosreact-redux, redux, and redux-thunk library.

npm install axios redux react-redux redux-thunk --save

# or

yarn add axios redux react-redux redux-thunk

#3: Create the action.

Now, we will fetch the data from Github API, and for that, we need to use Axios: promise based library to send the network request to a Github API server and fetch the data.

Now, the network request is the best example of an Asynchronous call. The redux-thunk middleware is useful to fetch the data from an API.

Inside the src folder, create three more folders, and their names are following.

  1. actions
  2. reducers
  3. containers

Now, first inside the actions folder, create one file called types.js and write the following code inside it.

// types.js

export const FETCH_GITHUB_DATA = 'FETCH_GITHUB_DATA';

When the page loads, we initiate the FETCH_GITHUB_DATA action and fetch all the data from the server and save it inside the Redux store. 

Now, that action returns the object that contains two properties.

  1. Action type
  2. Payload

As we know for our demo, we have two actions, so create one file inside src >> actions folder called index.js.

Add the following code inside the index.js.

// index.js

import { FETCH_GITHUB_DATA } from './types';
import axios from 'axios';

const apiUrl = 'https://api.github.com/users/KrunalLathiya';

export const fetchData = (data) => {
  return {
    type: FETCH_GITHUB_DATA,
    data
  }
};

export const fetchGithubData = () => {
  return (dispatch) => {
    return axios.get(apiUrl)
      .then(response => {
        dispatch(fetchData(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

So, here we have defined an action that calls the Github API and gets a response from the server. Remember, the reducer is a pure function, and we do not want any asynchronous call inside reducer, all the asynchronous actions are called here inside actions.

#4: Create the rootReducer and postReducer.

Now, inside the reducers folder, create one file called githubReducer.js.

Write the following code inside the githubReducer.js.

// githubReducer.js

import { FETCH_GITHUB_DATA } from '../actions/types';

export default function githubReducer(state = [], action) {
  switch (action.type) {
      case FETCH_GITHUB_DATA:
      return action.data;
    default:
      return state;
  }
}

This githubReducer.js file contains pure functions and does not relate to any backend service. Reducers must be pure functions.

So, if the action type is matched with the fired action, then it will modify the store and change the current state and give that mutated state.

Now, create an index.js file inside reducers folderWrite the following code inside it.

// index.js

import { combineReducers } from 'redux';
import data from './githubReducer';

export default combineReducers({
    data: data
});

#5: Configure the redux Store

Import the src >> reducers >> index.js reducer file inside src >> index.js file, which is already there. So, our final src >> index.js file looks like below.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

import App from './App';
import rootReducer from './reducers';
import { fetchGithubData } from './actions/index';

const store = createStore(rootReducer, applyMiddleware(thunk));

store.dispatch(fetchGithubData());

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));

Here, we have created the redux store. Also, imported the createStore, applyMiddleware, thunk.

Since we are dealing with Asynchronous data, we have to use the thunk to save the data inside the redux store, and then the redux store will update the state and update the React.js User Interface.

First, we have created the redux store and then apply redux-thunk middleware to the store. This middleware helps us to help with Async action inside the store.

After creating the store, we have dispatched the action that fetches all the data from the GitHub server and put it inside the Redux store. So, when our react app loads for the first time, we get the data.

#6: Display the data.

Now, inside the containers folder, create one container component called GithubData.jsf and write the following code.

// GithubData.js

import React from 'react';
import { connect } from 'react-redux';

function GithubData({ data }) {
  if(!data) {
    return (
      <div>
        No Data
      </div>
    )
  }
  return (
    <div>
      <div>
        Name: { data.name }
      </div>
      <br />
      <div>
        Blog: { data.blog }
      </div>
      <br />
      <div>
        Github Followers: { data.followers }
      </div>
    </div>
  );
}

const mapStateToProps = state => {
  return {
    data: state.data
  };
};

export default connect(
  mapStateToProps,
  null
)(GithubData);

So, here we have mapped the state data to properties of this component.

Save this file and go to the terminal and start the react dev server.

npm start

 

Redux thunk example

Head over to the browser and see the following output.

thunk example in redux

 

Finally, Redux Thunk Tutorial With Example From Scratch is over.

The post Redux Thunk Tutorial With Example From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/feed/ 1
React Native Redux Example Tutorial From Scratch https://appdividend.com/2018/08/04/react-native-redux-example-tutorial/ https://appdividend.com/2018/08/04/react-native-redux-example-tutorial/#comments Sat, 04 Aug 2018 10:15:14 +0000 http://localhost/wordpress/?p=1433 React Native Redux Tutorial Demo

React Native Redux Example Tutorial From Scratch is today’s leading topic. Redux is a standalone state management library, which can be used with any library or framework. If your background is React developer, then you have used the Redux library with React. The primary use of Redux is that we can use one application state as […]

The post React Native Redux Example Tutorial From Scratch appeared first on AppDividend.

]]>
React Native Redux Tutorial Demo

React Native Redux Example Tutorial From Scratch is today’s leading topic. Redux is a standalone state management library, which can be used with any library or framework. If your background is React developer, then you have used the Redux library with React. The primary use of Redux is that we can use one application state as a global state and interact with the state from any react component is very easy whether they are siblings or parent-child. Now, let us start the React Native Redux Example Tutorial by installing React Native on Mac first.

If you want to learn more about React Native and Redux then check out this course. The Complete React Native and Redux Course

React Native Redux Example Tutorial

We start our project by installing React Native CLI globally on the Mac. You can skip the following command if you have already installed.

#1: Install React Native.

Type the following command.

npm install -g react-native-cli

Okay, now for creating a new application, type the following command.

react-native init rncreate
cd rncreate

Now, after installing, we need to open this application in the two different Simulators.

For testing on iOS simulator, type the following command.

react-native run-ios

If you have configured XCode correctly, then one iOS device will pop up as well as development server will also start.

To open the project inside Android Simulator type the following command.

react-native run-android

Install the redux and react-redux library using the following command.

yarn add redux react-redux

# or

npm install redux react-redux --save

#2: Add Textbox and Button into the App.js.

Okay, so we will add a text box and button to add places. So let us add the TextInput and Button.  Also, we will add flexbox layout. Write the following code inside the App.js file.

// App.js

import React, {Component} from 'react';
import { StyleSheet, View, TextInput, Button } from 'react-native';

export default class App extends Component {

placeSubmitHandler = () => {
    console.log("Submitted");	
}

render() {
   return (
    <View style={ styles.container }>
       <View style = { styles.inputContainer }>
        <TextInput
           placeholder = "Seach Places"
           style = { styles.placeInput }
        ></TextInput>
        <Button title = 'Add' 
            style = { styles.placeButton }
            onPress = { this.placeSubmitHandler }
        />
        </View>
    </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 30,
    justifyContent: 'flex-start',
    alignItems: 'center',
  },
  inputContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    width: '100%'
  },
  placeInput: {
    width: '70%'
  },
  placeButton: {
    width: '30%'
  },
  listContainer: {
    width: '100%'
  }
});

#3: Define the state and input handler.

Okay, now we need a state to manage. So we define the initial state like following.

// App.js

state = {
   placeName: '',
   places: []
}

placeSubmitHandler = () => {
    console.log("Submitted");	
}

#4: Create the following folders inside Root.

Create the following folders.

  1. actions
  2. reducers
  3. components

Inside the actions folder, create one file called types.js. Add the following line inside types.js.

export const ADD_PLACE = 'ADD_PLACE'

Action type is the reducer’s operation type. Based on the action type the reducer case will be executed, and we modify the state in such a way that it remains pure. So we create a copy of the existing state and return a new state.

Now, create one more file called place.js in the same directory.

// place.js

import { ADD_PLACE } from './types';

export const addPlace = placeName => {
  return {
    type: ADD_PLACE,
    payload: placeName
  }
}

The addPlace() function returns an action. Now based on that action, reducers function’s case is executed.

But, we need to connect this action to our App.js component somehow. Otherwise, we can not add the data into the Redux store. Also, we need to first create a store. But before, we also need to create a reducer function. So, first create a reducer then create a store and then connect the React Native application to the Redux store.

#5: Create a Reducer function.

Inside reducers function, create one file called placeReducer.js. Add the following code inside it.

// placeReducer.js

import { ADD_PLACE } from '../actions/types';

const initialState = {
  placeName: '',
  places: []
};

const placeReducer = (state = initialState, action) => {
  switch(action.type) {
    case ADD_PLACE:
      return {
        ...state,
        places: state.places.concat({
          key: Math.random(),
          value: action.payload
        })
      };
    default:
      return state;
  }
}

export default placeReducer;

So, here, we have defined the function called placeReducer that accepts the two arguments.

  1. state
  2. action

The first time, it will take the initial state of our application, and then we pass whatever argument, it takes that argument and operates based on the case execution. The second argument is action, which consists of type and payload. The payload is the place name, we have entered inside the text box. So it adds the text box’s value inside places array.

Remeber here; we have returned a new state and not existing state. So we have modified the state in the pure manner and not existing state.

#6: Create a Redux Store.

Inside the root folder, create one file called store.js and add the following code.

// store.js

import { createStore, combineReducers } from 'redux';
import placeReducer from './reducers/placeReducer';

const rootReducer = combineReducers({
  places: placeReducer
});

const configureStore = () => {
  return createStore(rootReducer);
}

export default configureStore;

Here, we have created the redux store and passed the reducer to that store. The combineReducer function combines all the different reducers into one and forms the global state. So this is the global state of our whole application.

#7: Pass the Store to the React Native app.

Inside the root folder, you will find one file called index.js and inside that file add the following code.

// index.js

import { AppRegistry } from 'react-native';
import React from 'react';
import App from './App';
import { name as appName } from './app.json';
import { Provider } from 'react-redux';

import configureStore from './store';

const store = configureStore()

const RNRedux = () => (
  <Provider store = { store }>
    <App />
  </Provider>
)

AppRegistry.registerComponent(appName, () => RNRedux);

It is almost the same as React web application, in which we pass the Provider as a root element and pass the store and then via react-redux’s connect() function, we can connect the any react component to redux store.

#8: Connect React Native app to Redux store.

Finally, we connect our App.js component to the Redux store. For that, we need the connect() function from the react-redux library.

// App.js

import React, { Component } from 'react';
import { StyleSheet, View, TextInput, Button, FlatList } from 'react-native';
import ListItem from './components/ListItem';
import { connect } from 'react-redux';
import { addPlace } from './actions/place';

class App extends Component {

  state = {
    placeName: '',
    places: []
  }

  placeSubmitHandler = () => {
    if(this.state.placeName.trim() === '') {
      return;
    }
    this.props.add(this.state.placeName);
}

placeNameChangeHandler = (value) => {
  this.setState({
    placeName: value
  });    
}

placesOutput = () => {
   return (
    <FlatList style = { styles.listContainer }
      data = { this.props.places }
      keyExtractor={(item, index) => index.toString()}
      renderItem = { info => (
        <ListItem 
          placeName={ info.item.value }
        />
      )}
    />
  )
}

render() {
  return (
    <View style={ styles.container }>
      <View style = { styles.inputContainer }>
        <TextInput
          placeholder = "Seach Places"
          style = { styles.placeInput }
          value = { this.state.placeName }
          onChangeText = { this.placeNameChangeHandler }
        ></TextInput>
        <Button title = 'Add' 
          style = { styles.placeButton }
          onPress = { this.placeSubmitHandler }
        />
        </View>
        <View style = { styles.listContainer }>
          { this.placesOutput() }
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    paddingTop: 30,
    justifyContent: 'flex-start',
    alignItems: 'center',
  },
  inputContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    width: '100%'
  },
  placeInput: {
    width: '70%'
  },
  placeButton: {
    width: '30%'
  },
  listContainer: {
    width: '100%'
  }
});

const mapStateToProps = state => {
  return {
    places: state.places.places
  }
}

const mapDispatchToProps = dispatch => {
  return {
    add: (name) => {
      dispatch(addPlace(name))
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

Here, when we click the add button, we get the textbox value and then send it to the action with that value. Now that action returned the object with the action type and payload and based on the type the reducer will be executed and add that values inside the store.

Now, if the store’s values are changed, then we need to update the UI based on the new values. That is why the mapStateToProps function is created. So, when the store’s places array get the new value, render function executed again and update the UI.

The mapDispatchToProps function helps us to connect our application to the required action, so that action then further executed by a reducer and change the application state.

Also, inside the components folder, create one file called ListItem.js and add the following code inside it.

// ListItem.js

import React from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';

const ListItem = (props) => {
    return (
      <TouchableOpacity>
        <View style = { styles.listItem }>
          <Text>{ props.placeName }</Text>
        </View>
      </TouchableOpacity>
    );
}

const styles = StyleSheet.create({
  listItem: {
    width: '100%',
    padding: 10,
    marginBottom: 10,
    backgroundColor: '#eee'
  }
});

export default ListItem;

This component receives the properties from the parent component and displays the data in the proper format. Save the file and go to your Simulators and refresh the screen.

React Native Redux Example Tutorial From Scratch

 

Finally, React Native Redux Example Tutorial From Scratch is over. Thanks for taking.

The post React Native Redux Example Tutorial From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2018/08/04/react-native-redux-example-tutorial/feed/ 20
React Redux Axios Tutorial Example From Scratch https://appdividend.com/2018/06/15/react-redux-axios-tutorial-example/ https://appdividend.com/2018/06/15/react-redux-axios-tutorial-example/#comments Fri, 15 Jun 2018 20:20:52 +0000 http://localhost/wordpress/?p=1095 Redux React Axios Redux Thunk Tutorial With Example

React Redux Axios Tutorial Example From Scratch is the topic, we discuss today. In the last post, we have seen the working app on the client side using React and Redux. In this post, we will Store the data on the MongoDB database and use Express as a web framework. If you want to learn more about […]

The post React Redux Axios Tutorial Example From Scratch appeared first on AppDividend.

]]>
Redux React Axios Redux Thunk Tutorial With Example

React Redux Axios Tutorial Example From Scratch is the topic, we discuss today. In the last post, we have seen the working app on the client side using React and Redux. In this post, we will Store the data on the MongoDB database and use Express as a web framework.

If you want to learn more about React.js then check out this  React 16 – The Complete Guide (incl. React Router 4 & Redux) Guide. It has a very brief intro about React and Redux.
React 16 – The Complete Guide (incl. React Router 4 & Redux)

Async action in Redux is significant because in a real-time application, you always have backend and somehow you need to figure it out, how we can use Redux with backend service. We will use Axios promise based library to send a network request to the Node.js server.

We use redux-thunk middleware for async action. It is a quite famous library among the developers. At the first time, all the things look pretty complicated, but trust me, one step at a time will solve all your doubts and confusions. Redux is pretty complicated at first sight, and in this tutorial, redux-thunk is also there, so bear with me. We will figure it out how we can join all of these concepts and build a simple React Redux Axios Tutorial.

If you have not followed my previous tutorial on the client side then you can check out the below link.

Related PostHow To Connect React And Redux With Example

Workflow of this demo

  1. At the start of the application, we fire an action that fetches all the posts from the MongoDB database, if the data is not there then we display no posts.
  2. When we add a new post then first it fires an action that sends a POST request to the node.js server and express saves the data in the database and return that data in the JSON format.
  3. We get the json data when the promise resolves, and then we fire another action that calls the reducer function and saves the data in the Redux store.
  4. So, when we change the state using the Redux, the UI will change, and we get our first post at the front end.
  5. As we know, we use the database so that data will be persisted and you can verify that by refreshing the page, you get the same data.
  6. We do same for the delete, when we click the button, first it will send a delete request to the server and delete the document from mongodb, and then we pass the id to reducer function and filter it out our posts as well.

React Redux Axios Tutorial

We start our project by installing React.js.

Step 1: Install React.js.

Type the following command.

npm install -g create-react-app
create-react-app postreactredux

React Redux Axios Tutorial Example From Scratch

Step 2: Install Redux, react-redux, and redux-thunk.

Type the following command to install both of the libraries.

npm install redux react-redux --save

# or

yarn add redux react-redux

We also need a redux-thunk library for the async actions. Let us install using the following command.

npm install redux-thunk --save

Install the Bootstrap 4.

npm install bootstrap --save

Now, import this file inside src >> index.js.

// index.js

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Step 3: Create NewPost component.

If use react and redux together then separation of concern is there. Means, there are two types of components.

  1. Dumb Components(Presentational)
  2. Smart Component(Containers)

Dumb components render the data, and they did not care about any logic. They have nothing to do with a redux store.

Smart components are concern about logic and directly connected to the store.

Now, inside src foldercreate one file called NewPost.js.

// NewPost.js

import React from 'react';

class NewPost extends React.Component {
  state = {
    title: '',
    body: ''
  };

  handleInputChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    if (this.state.title.trim() && this.state.body.trim()) {
      console.log(this.state);
      this.handleReset();
    }
  };

  handleReset = () => {
    this.setState({
      title: '',
      body: ''
    });
  };

  render() {
    return (
      <div>
          <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
              <input
              type="text"
              placeholder="Title"
              className="form-control"
              name="title"
              onChange={ this.handleInputChange }
              value={ this.state.title }
            />
          </div>
          <div className="form-group">
            <textarea
              cols="19"
              rows="8"
              placeholder="Body"
              className="form-control"
              name="body"
              onChange={ this.handleInputChange }
              value={ this.state.body }>
            </textarea>
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary">Add Post</button>
            <button type="button" className="btn btn-warning" onClick={ this.handleReset }>
              Reset
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default NewPost;

So, this component has two form fields.

  1. title
  2. body

When the user submits the form, we can see both the form fields value inside the console.

Okay, now we need to import this NewPost.js file inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import NewPost from './components/NewPost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-6">
            <NewPost />
          </div>
          <div className="col-md-6">
            Display Post
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and start the development server by the following command.

Redux React Tutorial

 

Step 4: Create Node.js, Express, MongoDB backend.

First, install all the node.js dependencies using the following command.

npm install express body-parser mongoose --save

Also, need a nodemon server for dev dependency because we do need to restart the server automatically after saving the code.

npm install nodemon --save-dev

I am not explaining the step by step guide on how to create a backend, do what I say to build a backend. Okay, now inside the root of the React.js project, we need to create a new folder called server.

Inside the server folder, create one file called server.js and write the following code.

I am writing the final server.js file, so do not start the node server now because some files will not there until we create it.

// server.js

const express = require('express'),
    path = require('path'),
    bodyParser = require('body-parser'),
    cors = require('cors'),
    mongoose = require('mongoose'),
    config = require('./config/DB');

    const app = express();

    mongoose.Promise = global.Promise;
    mongoose.connect(config.DB).then(
      () => {console.log('Database is connected') },
      err => { console.log('Can not connect to the database'+ err)}
    );
    const postroutes = require('./routes/PostRoute');

    app.use(bodyParser.json());
    app.use(cors());
    const port = process.env.PORT || 4000;

    app.use('/posts', postroutes);

    const server = app.listen(port, function(){
     console.log('Listening on port ' + port);
    });

Inside server folder, create three more folders.

  1. models
  2. routes
  3. config

Inside config folder, create one file called DB.js. Write the following code in it.

// DB.js

module.exports = {
    DB: 'mongodb://localhost:27017/posts'
 };

Inside the models folder, create one file called Post.js and write the following code inside that file.

// Post.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Define collection and schema for Post
let Post = new Schema({
  title: {
    type: String
  },
  body: {
    type: String
  }
},{
    collection: 'posts'
});

module.exports = mongoose.model('Post', Post);

Inside routes folder, create one file called PostRoute.js. Write the following code inside it.

// PostRoute.js

const express = require('express');
const app = express();
const PostRoute = express.Router();

// Require Post model in our routes module
let Post = require('../models/Post');

// Defined store route
PostRoute.route('/add').post(function (req, res) {
  let post = new Post(req.body);
  post.save()
    .then(post => {
    res.status(200).json(post);
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

// Defined get data(index or listing) route
PostRoute.route('/').get(function (req, res) {
    Post.find(function (err, posts){
    if(err){
      console.log(err);
    }
    else {
      res.json(posts);
    }
  });
});

// Defined delete | remove | destroy route
PostRoute.route('/delete/:id').get(function (req, res) {
    Post.findByIdAndRemove({_id: req.params.id}, function(err, post){
        if(err) res.json(err);
        else res.json(req.params.id);
    });
});

module.exports = PostRoute;

So, our backend code is complete; now we need to start two servers.

  1. Node.js server
  2. MongoDB server

Start the MongoDB server using this command.

mongod

Go to the root of the React.js project and start the Node.js server using the following command.

nodemon server/server.js

If all of your configurations are proper, then you can see our Node.js application is connected to the MongoDB database. Now, from the client side, we can send a GET or POST request to this node.js express server.

Step 5: Create the actions.

Now, inside src folder, create three more folders, and their names are following.

  1. containers
  2. reducers
  3. actions

Now, first inside actions folder, create one file called types.js.

Write the following code inside it.

// types.js

export const ADD_POST = 'ADD_POST';
export const DELETE_POST = 'DELETE_POST';

export const FETCH_POST = 'FETCH_POST';

These are action types.

When the page loads, we initiate the FETCH_POST action and fetch all the data from the server and save it inside Redux store. When the user submits the form, we need to call these actions. So when a user creates a post, we will call ADD_POST action. This action then calls the reducer function and add the value to the store. So we can not directly modify the store, we need to create an action and then call the reducer function to alter the state of the store.

Same as a delete, when we try to delete any post, then DELETE_POST action will be triggered.

Now, that action returns an object that contains two properties.

  1. Action type
  2. Payload

As we know for our demo, we have two actions, so create one file inside src >> actions folder called index.js.

I am writing the whole code of index.js and explain it to you.

// index.js

import { ADD_POST, DELETE_POST, FETCH_POST } from './types';
import axios from 'axios';

const apiUrl = 'http://localhost:4000/posts';

export const createPost = ({ title, body }) => {
  return (dispatch) => {
    return axios.post(`${apiUrl}/add`, {title, body})
      .then(response => {
        dispatch(createPostSuccess(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

export const createPostSuccess =  (data) => {
  return {
    type: ADD_POST,
    payload: {
      _id: data._id,
      title: data.title,
      body: data.body
    }
  }
};

export const deletePostSuccess = id => {
  return {
    type: DELETE_POST,
    payload: {
      id
    }
  }
}

export const deletePost = id => {
  return (dispatch) => {
    return axios.get(`${apiUrl}/delete/${id}`)
      .then(response => {
        dispatch(deletePostSuccess(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

export const fetchPosts = (posts) => {
  return {
    type: FETCH_POST,
    posts
  }
};

export const fetchAllPosts = () => {
  return (dispatch) => {
    return axios.get(apiUrl)
      .then(response => {
        dispatch(fetchPosts(response.data))
      })
      .catch(error => {
        throw(error);
      });
  };
};

Here, we have defined the sync and async actions.

Sync action returns an object that contains action type and payload.

Async action send a network request to the server and wait for the promise to resolve. When the promise resolves, it fires a sync action with the action type and payload.

For our demo project, we need to fire async action three times to interact with the server.

  1. For fetching the data.
  2. For storing the data in the mongodb database.
  3. For deleting the data in the database.

Step 6: Create the rootReducer and postReducer.

Now, inside reducers folder, create one file called postReducer.js.

Write the following code inside it.

// postReducer.js

import { ADD_POST, DELETE_POST, FETCH_POST } from '../actions/types';

export default function postReducer(state = [], action) {
  switch (action.type) {
    case ADD_POST:
      return [...state, action.payload];
    case DELETE_POST:
      return state.filter(post => post._id !== action.payload.id);
      case FETCH_POST:
      return action.posts;
    default:
      return state;
  }
}

This file contains pure functions and does not relate to backend service. Reducers must be pure functions.

So, if the action type is matched with fired action, then it will modify the store and change the current state.

Now, create an index.js file inside reducers folder. Write the following code inside it.

// index.js

import { combineReducers } from 'redux';
import posts from './postReducer';

export default combineReducers({
    posts: posts
});

Step 7: Configure Store.

Import the src >> reducers >> index.js reducer file inside src >> index.js file.

So, our final src >> index.js file looks like below.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';

import App from './App';
import rootReducer from './reducers';
import { fetchAllPosts } from './actions/index';

import registerServiceWorker from './registerServiceWorker';

const store = createStore(rootReducer, applyMiddleware(thunk));

store.dispatch(fetchAllPosts());

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));

registerServiceWorker();

First, we have created the store and apply redux-thunk middleware to the store. This middleware helps us to deal with Async action inside the store.

After creating the store, we have dispatched the action that fetches all the post from the server and put it inside Redux store. So, when our app loads for the first time, we get the data if is there any in the database.

Step 8: Create a container component.

Inside containers folder, create a component called CreatePost.js.

// CreatePost.js

import { connect } from 'react-redux';
import { createPost } from '../actions';
import NewPost from '../components/NewPost';

const mapDispatchToProps = dispatch => {
  return {
    onAddPost: post => {
      dispatch(createPost(post));
    }
  };
};

export default connect(
  null,
  mapDispatchToProps
)(NewPost);

We have connected the NewPost component to the Redux store.

We have created the higher order component of NewPost.js file, and that is a CreatePost.js file.

Now, we import this CreatePost.js file inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            Posts
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Now, when the user submits the form, we can trigger an action, and that action call the reducer and modify the global state.

So, we can now access the action inside NewPost.js file.

// NewPost.js

import React from 'react';

class NewPost extends React.Component {
  state = {
    title: '',
    body: ''
  };

  handleInputChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    if (this.state.title.trim() && this.state.body.trim()) {
      this.props.onAddPost(this.state);
      this.handleReset();
    }
  };

  handleReset = () => {
    this.setState({
      title: '',
      body: ''
    });
  };

  render() {
    return (
      <div>
          <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
              <input
              type="text"
              placeholder="Title"
              className="form-control"
              name="title"
              onChange={ this.handleInputChange }
              value={ this.state.title }
            />
          </div>
          <div className="form-group">
            <textarea
              cols="19"
              rows="8"
              placeholder="Body"
              className="form-control"
              name="body"
              onChange={ this.handleInputChange }
              value={ this.state.body }>
            </textarea>
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary">Add Post</button>
            <button type="button" className="btn btn-warning" onClick={ this.handleReset }>
              Reset
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default NewPost;

Step 9: Display the Post.

Create a component inside components folder called Post.js and write the following code inside it.

Post.js component is responsible for rendering out our all the Posts.

// Post.js

import React from 'react';

const styles = {
  borderBottom: '2px solid #eee',
  background: '#fafafa',
  margin: '.75rem auto',
  padding: '.6rem 1rem',
  maxWidth: '500px',
  borderRadius: '7px'
};

export default ({ post: { title, body, _id }, onDelete }) => {
  return (
    <div style={ styles }>
      <h2>{ title }</h2>
      <p>{ body }</p>
      <button className="btn btn-danger" type="button" onClick={() => onDelete(_id)}>
        Remove
      </button>
    </div>
  );
};

So, this component only accepts the data of title, body, and _id and render it.

It also accepts the onDelete() function that can trigger the delete action and then that action calls the postReducer function and delete the post and state has been updated and also our UI will be updated.

Now, inside containers folder, create one container component called PostList.js file and write the following code.

// PostList.js

import React from 'react';
import { connect } from 'react-redux';
import Post from '../components/Post';
import { deletePost } from '../actions';

function PostList({ posts, onDelete }) {
  if(!posts.length) {
    return (
      <div>
        No Posts
      </div>
    )
  }
  return (
    <div>
      {posts.map(post => {
        return (
          <Post post={ post } onDelete={ onDelete } key={ post._id } />
        );
      })}
    </div>
  );
}

const mapStateToProps = state => {
  return {
    posts: state.posts
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onDelete: id => {
      dispatch(deletePost(id));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(PostList);

Now, this component gets the latest state from the store. When the new post is added, this component is notified because this component is directly connected to the store.

If the delete action is triggered, then it will filter out that post and display the remaining posts.

Now, a final thing is import this PostList.js component inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';
import PostList from './containers/PostList';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            <PostList />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and go to the http://localhost:3000/

If you have not started the React development server, then start a server by this command: yarn start

If everything configured correctly, then we can be able to adddisplay, and delete the post.

 

React Redux Example Tutorial

I have put this code on Github if you find any error during the execution of this project, then please check out my Github code, it might be helpful to you.

Github Code

Steps To Use Code

  1. Clone the repository.
  2. Go to the project folder and install dependencies using this command: npm install
  3. Start the mongodb server using this command: mongod
  4. Start the Node.js server using this command: nodemon server/server
  5. Start the Reacyt.js dev server using this command: yarn start

Finally, React Redux Axios Tutorial Example is over. Thanks for taking.

The post React Redux Axios Tutorial Example From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2018/06/15/react-redux-axios-tutorial-example/feed/ 11
How To Connect React and Redux With Example https://appdividend.com/2018/06/14/how-to-connect-react-and-redux-with-example/ https://appdividend.com/2018/06/14/how-to-connect-react-and-redux-with-example/#comments Thu, 14 Jun 2018 17:21:56 +0000 http://localhost/wordpress/?p=1078 Connect React.js and Redux Example

In this tutorial, we will see How To Connect React and Redux With Example. For this simple demo, we will not be going to use any backend; we will do that in the next tutorial. We keep this example very simple and make it work at the client side. We create a simple post and display it, […]

The post How To Connect React and Redux With Example appeared first on AppDividend.

]]>
Connect React.js and Redux Example

In this tutorial, we will see How To Connect React and Redux With Example. For this simple demo, we will not be going to use any backend; we will do that in the next tutorial. We keep this example very simple and make it work at the client side. We create a simple post and display it, but we are going to manage it via Redux store. We can create and delete the post, and our store will handle all the data. We use Bootstrap 4 for the frontend.

If you are new to Redux then please check out my following article.

Read This FirstRedux Tutorial With Example From Scratch

Also, you can take the following course.

If you want to learn more about React.js then check out this  React 16 – The Complete Guide (incl. React Router 4 & Redux) Guide. It has a very brief intro about React and Redux.
React 16 – The Complete Guide (incl. React Router 4 & Redux)

How To Connect React and Redux With Example

The API for the React Redux bindings is straightforward: a Provider component that makes our store accessible throughout our app and a connect function that creates container components that can read the state from the store and dispatch actions. First, we install the React.js and right now the latest version of React.js is 16.4.1.

Step 1: Install React.js.

Type the following command.

npm install -g create-react-app
create-react-app postreactredux

 

How To Connect React and Redux With Example

Step 2: Install Redux and react-redux.

Type the following command to install both of the libraries.

npm install redux react-redux --save

# or

yarn add redux react-redux

Also, install the Bootstrap 4 using the following command.

npm install bootstrap --save

Now, import this file inside src >> index.js.

// index.js

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Step 3: Create NewPost component.

If use react and redux together then separation of concern is there. Means, there are two types of components.

  1. Dumb Components
  2. Smart Component(Containers)

Dumb components render the data, and they did not care about any logic. They have nothing to do with a redux store.

Smart components are concern about logic and directly connected to the store.

Now, inside src foldercreate one file called NewPost.js.

// NewPost.js

import React from 'react';

class NewPost extends React.Component {
  state = {
    title: '',
    body: ''
  };

  handleInputChange = e => {
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  handleSubmit = e => {
    e.preventDefault();
    if (this.state.title.trim() && this.state.body.trim()) {
      console.log(this.state);
      this.handleReset();
    }
  };

  handleReset = () => {
    this.setState({
      title: '',
      body: ''
    });
  };

  render() {
    return (
      <div>
          <form onSubmit={ this.handleSubmit }>
          <div className="form-group">
              <input
              type="text"
              placeholder="Title"
              className="form-control"
              name="title"
              onChange={ this.handleInputChange }
              value={ this.state.title }
            />
          </div>
          <div className="form-group">
            <textarea
              cols="19"
              rows="8"
              placeholder="Body"
              className="form-control"
              name="body"
              onChange={ this.handleInputChange }
              value={ this.state.body }>
            </textarea>
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary">Add Post</button>
            <button type="button" className="btn btn-warning" onClick={ this.handleReset }>
              Reset
            </button>
          </div>
        </form>
      </div>
    );
  }
}

export default NewPost;

So, this component has two form fields.

  1. title
  2. body

When the user submits the form, we can see both the form fields value inside the console.

Okay, now we need to import this NewPost.js file inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import NewPost from './components/NewPost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row">
          <div className="col-md-6">
            <NewPost />
          </div>
          <div className="col-md-6">
            Display Post
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and start the development server by the following command.

Redux React Tutorial

 

Step 4: Create the actions.

Now, inside src folder, create three more folders, and their names are following.

  1. containers
  2. reducers
  3. actions

Now, first inside actions folder, create one file called types.js.

Write the following code inside it.

// types.js

export const ADD_POST = 'ADD_POST';
export const DELETE_POST = 'DELETE_POST';

These are action types. When the user submits the form, we need to call these actions. So when a user creates a post, we will call ADD_POST action. This action then calls the reducer function and add the value to the store. So we can not directly modify the store, we need to create an action and then call the reducer function to alter the state of the store.

Same as a delete, when we try to delete any post, then DELETE_POST action will be triggered.

Now, that action returns an object that contains two properties.

  1. Action type
  2. Payload

As we know for our demo, we have two actions, so create one file inside src >> actions folder called index.js.

But, before that, we need every post a different IDs, so for generating ID on the client side, we use the npm library called uuid.

npm install uuid --save

# or

yarn add uuid

Now, write the following code inside src >> actions >> index.js file.

// actions >> index.js

import uuidv4 from 'uuid/v4';
import { ADD_POST, DELETE_POST } from './types';

export const createPost = ({ title, body }) => ({
  type: ADD_POST,
  payload: {
    id: uuidv4(),
    title,
    body
  }
});

export const deletePost = id => ({
  type: DELETE_POST,
  payload: {
    id
  }
});

So, the createPost function accepts title and body as a parameter and return an object.

We add an extra payload called an id so that we can render different posts and delete according to their IDs.

Step 5: Create the rootReducer and postReducer.

Now, inside reducers folder, create one file called postReducer.js.

// postReducer.js

import { ADD_POST, DELETE_POST } from '../actions/types';

export default function postReducer(state = [], action) {
  switch (action.type) {
    case ADD_POST:
      return [...state, action.payload];
    case DELETE_POST:
      return state.filter(post => post.id !== action.payload.id);
    default:
      return state;
  }
}

So, if the action type is matched with fired action, then it will modify the store and change the current state.

Now, create an index.js file inside reducers folder. Write the following code inside it.

// index.js

import { combineReducers } from 'redux';
import posts from './postReducer';

export default combineReducers({
    posts: posts
});

Step 6: Configure Store.

Import this index.js reducer file inside src >> index.js file.

So, our final src >> index.js file looks like below.

// src >> index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

import App from './App';
import rootReducer from './reducers';

import registerServiceWorker from './registerServiceWorker';

const store = createStore(rootReducer);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, document.getElementById('root'));

registerServiceWorker();

Step 7: Create a container component.

Inside containers folder, create a component called CreatePost.js.

// CreatePost.js

import { connect } from 'react-redux';
import { createPost } from '../actions';
import NewPost from '../components/NewPost';

const mapDispatchToProps = dispatch => {
  return {
    onAddPost: post => {
      dispatch(createPost(post));
    }
  };
};

export default connect(
  null,
  mapDispatchToProps
)(NewPost);

We have connected the NewPost component to the Redux store.

We have created the higher order component of NewPost.js file, and that is a CreatePost.js file.

Now, we import this CreatePost.js file inside src >> App.js file.

// src >> App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            Display Post
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Now, when the user submits the form, we can trigger an action, and that action call the reducer and modify the global state.

So, we can now access the action inside NewPost.js file.

// NewPost.js

handleSubmit = e => {
  e.preventDefault();
  if (this.state.title.trim() && this.state.body.trim()) {
    this.props.onAddPost(this.state);
    this.handleReset();
  }
};

So, now you can be able to track the state inside the store. You can modify the state through actions.

Step 8: Display the Post.

Create a component inside components folder called Post.js and write the following code inside it.

Post.js component is responsible for rendering out our all the Posts.

// Post.js

import React from 'react';

const styles = {
  borderBottom: '2px solid #eee',
  background: '#fafafa',
  margin: '.75rem auto',
  padding: '.6rem 1rem',
  maxWidth: '500px',
  borderRadius: '7px'
};

export default ({ post: { title, body, id }, onDelete }) => {
  return (
    <div style={ styles }>
      <h2>{ title }</h2>
      <p>{ body }</p>
      <button className="btn btn-danger" type="button" onClick={() => onDelete(id)}>
        Remove
      </button>
    </div>
  );
};

So, this component only accepts the data of title, body, and id and render it.

It also accepts the onDelete() function that can trigger the delete action and then that action calls the postReducer function and delete the post and state has been updated and also our UI will be updated.

Now, inside containers folder, create one container component called PostList.js file and write the following code.

// PostList.js

import React from 'react';
import { connect } from 'react-redux';
import Post from '../components/Post';
import { deletePost } from '../actions';

function PostList({ posts, onDelete }) {
  return (
    <div>
      {posts.map(post => {
        return (
          <Post post={ post } onDelete={ onDelete } key={ post.id } />
        );
      })}
    </div>
  );
}

const mapStateToProps = state => {
  return {
    posts: state.posts
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onDelete: id => {
      dispatch(deletePost(id));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(PostList);

Now, this component gets the latest state from the store. When the new post is added, this component is notified because this component is directly connected to the store.

If the delete action is triggered, then it will filter out that post and display the remaining posts.

Now, a final thing is import this PostList.js component inside src >> App.js file.

// src >> App.js

import React, { Component } from 'react';
import CreatePost from './containers/CreatePost';
import PostList from './containers/PostList';

import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

const stylesApp = {
  marginTop: 40
}

class App extends Component {
  render() {
    return (
      <div className="container">
        <div className="row" style={ stylesApp }>
          <div className="col-md-6">
            <CreatePost />
          </div>
          <div className="col-md-6">
            <PostList />
          </div>
        </div>
      </div>
    );
  }
}

export default App;

Save the file and go to the http://localhost:3000/

If everything configured correctly then we can be able to add, display, and delete the post.

React Redux Example Tutorial

 

I have put this code on Github, if you find any error during the execution of this project then please check out my Github code, it might be helpful to you.

Github Code

Steps To Use Github Code.

  1. Clone the repo.
  2. Go to the project folder and install dependencies: npm install
  3. Start the dev server by this command: yarn start

Finally, How To Connect React and Redux With Example is over. Thanks.

The post How To Connect React and Redux With Example appeared first on AppDividend.

]]>
https://appdividend.com/2018/06/14/how-to-connect-react-and-redux-with-example/feed/ 1
Redux Form Validation Tutorial Example https://appdividend.com/2017/11/05/redux-form-validation-tutorial-example/ https://appdividend.com/2017/11/05/redux-form-validation-tutorial-example/#respond Sun, 05 Nov 2017 14:03:52 +0000 http://localhost/appdividend/?p=1232 Redux Form Validation Tutorial Example From Scratch

Redux Form Validation Tutorial Example From Scratch is today’s leading topic. The underlying implementation of redux-form is simple. However, to make the most of it, it is recommended to have basic knowledge on: If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router […]

The post Redux Form Validation Tutorial Example appeared first on AppDividend.

]]>
Redux Form Validation Tutorial Example From Scratch

Redux Form Validation Tutorial Example From Scratch is today’s leading topic. The underlying implementation of redux-form is simple. However, to make the most of it, it is recommended to have basic knowledge on:

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.
  1. Redux state container,
  2. React and Higher-Order Components (HOCs).

To connect your React form components to your Redux store, you will need following pieces from the redux-form  package:

  • Redux Reducer: form reducer
  • React HOC reduxForm() and <Field /> component.

Prerequisites

  1. Simple Redux Create Delete Contact Application.

  2. Redux Tutorial With Example From Scratch.

Redux Form Validation Tutorial

First, we need to setup the Redux Store and then pass to the main component. Also, we need to install some redux related libraries to up and running with this project.

Step 1: Setup the project and install dependencies.

Hit the following commands one by one to set up the boilerplate.

npm install -g create-react-app

create-react-app reduxformvalidation

npm i -D redux react-redux redux-form

Now, type the following command.

npm start

If any error occurs, please hit the following command.

npm install

Then, again try the following command, it will open the http://localhost:3000 URL in the browser.

We need to style the form components, so here I have used Bootstrap 4 Forms.

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <title>Redux Form Validation</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Step 2: Create a redux store.

Create one store and pass wrap with the Provider component.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { reducer as formReducer } from 'redux-form';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

const rootReducer = combineReducers({
    form: formReducer
});

const store = createStore(rootReducer);

ReactDOM.render(
<Provider store={store}>
 <App />
</Provider>
,document.getElementById('root'));
registerServiceWorker();

Step 3: Create only FormCode.js file.

Inside src directory, make one file called FormCode.js file.
To make your form component communicate with the store, we need to wrap it with reduxForm(). It will provide the props about the form state and function to handle the submission process.

// FormCode.js

import React from 'react';
import { Field, reduxForm } from 'redux-form';

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
    <div>
      <label className="control-label">{label}</label>
      <div>
        <input {...input} placeholder={label} type={type} className="form-control" />
        {touched && ((error && <span className="text-danger">{error}</span>) || (warning && <span>{warning}</span>))}
      </div>
    </div>
  )

let FormCode = props => {
  const { handleSubmit, pristine, submitting } = props;
  return (
    <form onSubmit={ handleSubmit }>
      <div className="form-group">
        <Field name="firstName" component={renderField} label="First Name" />
      </div>
      <div className="form-group">
        <Field name="lastName" component={renderField} label="Last Name" />
      </div>
      <div className="form-group">
        <Field name="email" component={renderField} label="Email" />
      </div>
      <div className="form-group">
        <button type="submit" className="btn btn-primary">Submit</button>
      </div>
    </form>
  )
}
FormCode = reduxForm({
  form: 'contact'
})(FormCode);

export default FormCode;

FormCode.js is just a web form component with its form field. We have designed the form and its error, but we have still not write any validation logic in it. Just plain Bootstrap Form.

Step 4: Include this form into React component.

// App.js

import React from 'react';
import FormCode from './FormCode';

class App extends React.Component {
  submit = (values) => {
    alert("submitted");
    console.log(values);
  }
  render() {
    return (
      <div className="container">
        <h3 className="jumbotron">Redux Form Validation</h3>
        <FormCode onSubmit={this.submit} />
      </div>
      
    )
  }
}

export default App;

Now, switch to the browser, you can see the bootstrap form ready.  If you try to submit the form then, it will not validate any field because we have not write any validation logic and you can see the alert that said: “submitted.”

Step 5: Write and add validation logic.

In FormCode.js file, write the following code.

// App.js

const validate = values => {
    const errors = {}
    if (!values.firstName) {
      errors.firstName = 'Required'
    } else if (values.firstName.length < 2) {
      errors.firstName = 'Minimum be 2 characters or more'
    }
    if (!values.email) {
      errors.email = 'Required'
    } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
      errors.email = 'Invalid email address'
    }
    if (!values.lastName) {
        errors.lastName = 'Required'
      } else if (values.lastName.length < 2) {
        errors.lastName = 'Minimum be 2 characters or more'
      }
    return errors
  }

Now, we need to pass this function into the FormCode.js component. Since it is HOC component, it is straightforward to do so.

// App.js

FormCode = reduxForm({
  form: 'contact',
  validate,
})(FormCode);

export default FormCode;

So, our complete FormCode.js file looks like this.

// FormCode.js

import React from 'react';
import { Field, reduxForm } from 'redux-form';

const validate = values => {
    const errors = {}
    if (!values.firstName) {
      errors.firstName = 'Required'
    } else if (values.firstName.length < 2) {
      errors.firstName = 'Minimum be 2 characters or more'
    }
    if (!values.email) {
      errors.email = 'Required'
    } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
      errors.email = 'Invalid email address'
    }
    if (!values.lastName) {
        errors.lastName = 'Required'
      } else if (values.lastName.length < 2) {
        errors.lastName = 'Minimum be 2 characters or more'
      }
    return errors
  }

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
    <div>
      <label className="control-label">{label}</label>
      <div>
        <input {...input} placeholder={label} type={type} className="form-control" />
        {touched && ((error && <span className="text-danger">{error}</span>) || (warning && <span>{warning}</span>))}
      </div>
    </div>
  )

let FormCode = props => {
  const { handleSubmit, pristine, submitting } = props;
  return (
    <form onSubmit={ handleSubmit }>
      <div className="form-group">
        <Field name="firstName" component={renderField} label="First Name" />
      </div>
      <div className="form-group">
        <Field name="lastName" component={renderField} label="Last Name" />
      </div>
      <div className="form-group">
        <Field name="email" component={renderField} label="Email" />
      </div>
      <div className="form-group">
        <button type="submit" disabled={pristine || submitting} className="btn btn-primary">Submit</button>
      </div>
    </form>
  )
}
FormCode = reduxForm({
  form: 'contact',
  validate,
})(FormCode);

export default FormCode;

 

Redux Form v6 Validation Example Tutorial From Scratch

Fork Me On Github

Finally, our Redux Form Validation Tutorial Example From Scratch is over.

 

The post Redux Form Validation Tutorial Example appeared first on AppDividend.

]]>
https://appdividend.com/2017/11/05/redux-form-validation-tutorial-example/feed/ 0
Simple Redux Create Delete Contact Application https://appdividend.com/2017/11/02/simple-redux-create-delete-contact-application/ https://appdividend.com/2017/11/02/simple-redux-create-delete-contact-application/#comments Thu, 02 Nov 2017 22:14:42 +0000 http://localhost/appdividend/?p=1220 Simple Redux Create Delete Contact Application

Simple Redux Create Delete Contact Application is today’s small project. We will use ReactJS as a frontend. We are not using any backend in this tutorial, so a just client-side application. Redux is the most famous library to manage the state at the client side, and it is trendy among React community. We will build a Simple […]

The post Simple Redux Create Delete Contact Application appeared first on AppDividend.

]]>
Simple Redux Create Delete Contact Application

Simple Redux Create Delete Contact Application is today’s small project. We will use ReactJS as a frontend. We are not using any backend in this tutorial, so a just client-side application. Redux is the most famous library to manage the state at the client side, and it is trendy among React community. We will build a Simple Contact Create Delete Application. In that user can add a new contact and it will display as a list and user can also delete any contact.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

Redux Create Delete Contact App

First, we need to download the create-react-app globally on the PC and then we can begin our project.

Step 1: Do one ReactJS Project

Type the following command one by one.

npm install -g create-react-app
create-react-app redux-contact-app

It will make some boilerplate for our application and also install all the dependencies for our project. Still, we need to establish some other dependencies as well.

npm install --save redux react-redux

So, this installs redux and react-redux dependencies.

Step 2: We need to configure the Redux Store

First, we need to make three folders inside src directory.

  1. actions
  2. reducers
  3. store

To set the store, we need to create one file inside store folder called configureStore.js.

// configureStore.js

import { createStore } from 'redux';

export default function configureStore(initialState) {
    return createStore();
}

Also, we need to wrap the Provider component Outside our App.js component in the index.js file.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';

import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(
<Provider>
    <App />
</Provider>, document.getElementById('root'));
registerServiceWorker();

The react-redux library provides us Provider, which wraps the App component and make the available store to the context of our application. 

Step 3: We need to make one form to add the contact name.

Go to the App.js file and put the following code in it.

// App.js

import React, { Component } from 'react';

class App extends Component {

  constructor(props){
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.state = {
      name: ''
    }
  }

  handleChange(e){
    this.setState({
      name: e.target.value
    })
  }

  handleSubmit(e){
    e.preventDefault();
    console.log(this.state.name);
  }

  render() {
    let name;
    return(
      <div>
        <h1>Clientside Contacts Application</h1>
        <hr />
        {/* <ul>
          {this.props.contacts.map((contact, i) => <li key={i}>{contact.name}</li> )}
        </ul> */}
        <div>
          <h3>Add Contact Form</h3>
          <form onSubmit={this.handleSubmit}>
            <input type="text" onChange={this.handleChange} />
            <input type="submit" />
          </form>
        </div>
      </div>
    )
  }
}

export default App;

So, it will create a form and when we submit the data, the data logs in the console.

Now, if we need to change the add the new contact in the array of contacts or modify it, we do not do it directly. We need to dispatch the actions and that actions call the reducer and reducer returns a new state of the application.

Step 4: Make actionType.js constants file.

We need to make one file called actionType.js inside the actions folder.

// actionTypes.js

export const GET_ALL_CONTACTS = 'GET_ALL_CONTACTS';
export const CREATE_NEW_CONTACT = 'CREATE_NEW_CONTACT';

This file exports our actionType for every action object. So every time, if we want to dispatch any actions then we access the actions quickly to avoid any typos in action types.

Step 5: Make one action object for creating contact.

Inside actions folder, make one file called contactAction.js.

// contactAction.js

import * as actionTypes from './actionTypes';

export const createContact = (contact) => {
    return {
      type: actionTypes.CREATE_NEW_CONTACT,
      contact: contact
    }
  };

createContact() function returns an object that describes two things.

  1. action type
  2. payload

Step 6: Make one reducer inside reducers folder.

Reducers are used to update the state object in your store. Just like actions, your application can have multiple reducers.

// contactReducer.js

import * as actionTypes from '../actions/actionTypes';

export default (state = [], action) => {
    switch (action.type){
      
      case actionTypes.CREATE_NEW_CONTACT:
      return [
        ...state,
        Object.assign({}, action.contact)
      ];
      default:
            return state;
    }
  };

Here, one thing to note that, we have not mutated the state directly instead we have returned a new state.

So, the new state is original state array + new contact data and returns a new collection.

Step 7: Create combineReducer function.

Inside reducers folder, make one file called index.js file.

// index.js

import { combineReducers } from 'redux';
import contacts from './contactReducer';

export default combineReducers({
    contacts: contacts
});

Now, update the configureStore function and pass the rootReducer to it.

// configureStore.js

import {createStore} from 'redux';
import rootReducer from '../reducers';

export default function configureStore(initialState) {
  return createStore(rootReducer, initialState);
}

Also, we need to pass the store in our application. So we need also to update the index.js file.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import registerServiceWorker from './registerServiceWorker';
import configureStore from './store/configureStore';

const store = configureStore();

ReactDOM.render(
<Provider store={store}>
    <App />
</Provider>, document.getElementById('root'));
registerServiceWorker();

Step 8: We need to connect this store to the App.js component.

If we want to access all the contacts data from the store, then we must the store state as props to the react components. 

Connect() function bridge the gap between store and components and provide a way to pass state as props to display data or dispatch any actions to the Redux store.

// App.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as contactAction from './actions/contactAction';

class App extends Component {

  constructor(props){
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.state = {
      name: ''
    }
  }

  handleChange(e){
    this.setState({
      name: e.target.value
    })
  }

  handleSubmit(e){
    e.preventDefault();
    let contact = {
      name: this.state.name
    }
    this.props.createContact(contact);
  }

  render() {

    return(
      <div>
        <h1>Clientside Contacts Application</h1>
        <hr />
        { <ul>
          {this.props.contacts.map((contact, i) => <li key={i}>{contact.name}</li> )}
        </ul> }
        <div>
          <h3>Add Contact Form</h3>
          <form onSubmit={this.handleSubmit}>
            <input type="text" onChange={this.handleChange} />
            <input type="submit" />
          </form>
        </div>
      </div>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    contacts: state.contacts
  }
};

const mapDispatchToProps = (dispatch) => {
  return {
    createContact: contact => dispatch(contactAction.createContact(contact))
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

Now, we can add the contacts, and it will list down the contact one by one from the store.

Step 9: Make an action to remove the contact list and style the project.

First, update the actionType.js file and add new action type.

// actionType.js

export const GET_ALL_CONTACTS = 'GET_ALL_CONTACTS';
export const CREATE_NEW_CONTACT = 'CREATE_NEW_CONTACT';
export const REMOVE_CONTACT = 'REMOVE_CONTACT';

We need to make an action described object in the contactAction.js file.

// contactAction.js

import * as actionTypes from './actionTypes';

export const createContact = (contact) => {
    return {
      type: actionTypes.CREATE_NEW_CONTACT,
      contact: contact
    }
  };

export const deleteContact = (id) => {
    return {
        type: actionTypes.REMOVE_CONTACT,
        id: id
    }
}

Now, add a new case in the contactReducer.js file to delete the contact.

// contactReducer.js

import * as actionTypes from '../actions/actionTypes';

export default (state = [], action) => {
    switch (action.type){
      case actionTypes.CREATE_NEW_CONTACT:
      return [
        ...state,
        Object.assign({}, action.contact)
      ];
      case actionTypes.REMOVE_CONTACT:
      return state.filter((data, i) => i !== action.id);
      default:
            return state;
    }
  };

In here, I have used the ES6 Filter function to remove the item list match with the id we just pass as a payload.

Finally, our App.js file looks like this with bootstrap styles.

// App.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as contactAction from './actions/contactAction';

class App extends Component {

  constructor(props){
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
     
    this.state = {
      name: ''
    }
  }

  handleChange(e){
    this.setState({
      name: e.target.value
    })
  }

  handleSubmit(e){
    e.preventDefault();
    let contact = {
      name: this.state.name
    }
    this.setState({
      name: ''
    });
    this.props.createContact(contact);
  }

  listView(data, index){
    return (
      <div className="row">
        <div className="col-md-10">
          <li key={index} className="list-group-item clearfix">
            {data.name}
          </li>
        </div>
        <div className="col-md-2">
          <button onClick={(e) => this.deleteContact(e, index)} className="btn btn-danger">
            Remove
          </button>
        </div>
    </div> 
    )
  }

  deleteContact(e, index){
    e.preventDefault();
    this.props.deleteContact(index);
  }

  render() {

    return(
      <div className="container">
        <h1>Clientside Contacts Application</h1>
        <hr />
        <div>
          <h3>Add Contact Form</h3>
          <form onSubmit={this.handleSubmit}>
            <input type="text" onChange={this.handleChange} className="form-control" value={this.state.name}/><br />
            <input type="submit" className="btn btn-success" value="ADD"/>
          </form>
          <hr />
        { <ul className="list-group">
          {this.props.contacts.map((contact, i) => this.listView(contact, i))}
        </ul> }
        </div>
      </div>
    )
  }
}

const mapStateToProps = (state, ownProps) => {
  return {
    contacts: state.contacts
  }
};

const mapDispatchToProps = (dispatch) => {
  return {
    createContact: contact => dispatch(contactAction.createContact(contact)),
    deleteContact: index =>dispatch(contactAction.deleteContact(index))
  }
};

export default connect(mapStateToProps, mapDispatchToProps)(App);

So, our Application looks like below.

React Redux CRUD Application

 

Our basic React Redux Create Delete Contact Application is over. You can download the project from GitHub.

Fork Me On GitHub

 

The post Simple Redux Create Delete Contact Application appeared first on AppDividend.

]]>
https://appdividend.com/2017/11/02/simple-redux-create-delete-contact-application/feed/ 4
Redux Tutorial With Example From Scratch https://appdividend.com/2017/08/23/redux-tutorial-example-scratch/ https://appdividend.com/2017/08/23/redux-tutorial-example-scratch/#comments Wed, 23 Aug 2017 15:08:55 +0000 http://localhost/appdividend/?p=932 Redux Tutorial With Example From Scratch

Redux Tutorial Step By Step With Example From Scratch is the topic we will cover. I will teach you Redux step by step. Redux is quite an excellent State Managment Framework usually used with React.js library. In Single Page Application, data management at client side is far more complicated than just imagine. Now, you are familiar that, ReactJS is relying on the […]

The post Redux Tutorial With Example From Scratch appeared first on AppDividend.

]]>
Redux Tutorial With Example From Scratch

Redux Tutorial Step By Step With Example From Scratch is the topic we will cover. I will teach you Redux step by step. Redux is quite an excellent State Managment Framework usually used with React.js library. In Single Page Application, data management at client side is far more complicated than just imagine. Now, you are familiar that, ReactJS is relying on the State of the application. However, In React.js state management is possible, but when the application gets bigger and bigger, unwanted errors and data changes are detected, and which module has changed which state and which view is updated, all these matters get complex, and we feel like, we trapped in our application. Facebook gives the solutionIts developer has created one State management pattern called Flux.

If you want to learn more about React and Redux then check out this React 16.6 – The Complete Guide (incl. React Router & Redux) course.

Flux

It complements React’s composable view components by utilizing the unidirectional data flow. When the users interact with views, the views propagates actions through a central dispatcher, to the various stores that hold the application data and logic, which updates all of our views that are affected.

Flux has so many stores, and each store is using different small part of the state or data of our application. In other words, each different module has its store.

Redux Tutorial 2017

Flux Data Flow

  1. The user interacts with the view and view triggers an action.
  2. Action dispatch the corresponding function and then that function change the store.
  3. When store updates its data, the subscriber views are automatically updated. We do not need to modify the data in different modules manually.

It is a unidirectional data flow. When the application gets bigger and bigger, then multiple stores manage the data. So that scenario will look like this.

 

React Redux Tutorial 2017

When multiple stores are there, the condition of our application looks like above figure, but the data flow is Unidirectional.

Flux has Multiple Stores.

Redux

Redux is the predictable state container for JavaScript applications. Redux is also following the Unidirectional flow, but it is entirely different from Flux. Flux has multiple stores.

Redux has a Single Store.

Latest Redux Tutorial Step By Step With Example From Scratch

Redux can not have multiple stores. The store is divided into various state objects. So all we need is to maintain the single store, or we can say the only source of truth.

Three Principles Of Redux

  1. Single source of truth.

  2. The state is read-only.

  3. Changes are made with pure functions.

It is the state of our whole application is stored in an object within a single store.  There is an only way to change the state is to emit an action, an object describing what happened. To specify how actions transform the state, you write pure reducers.

Actions

Actions are payloads of information that send data from your application to your store. You send them to the store using.store.dispatch()

Actions are plain JavaScript objects. Actions must have a type property that indicates the type of action being performed. Types should typically be defined as string constants.

import { ADD_TODO, REMOVE_TODO } from '../actionTypes'

Action Creators

Action creators are exactly the functions that create actions.

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

Reducers

Actions describe the fact that something happened but don’t specify how the application’s state changes in response. That is the job of reducers.

Handling Actions

(previousState, action) => newState

This is called a reducer because it is the type of function you would pass to Array.prototype.reduce(reducer, ?initialValue). It is essential that the reducer stay pure.

Following are the things you should never do inside a reducer:

  • Mutate reducer’s arguments;
  • Perform side effects like database calls, API calls, and routing transitions;
  • Call non-pure functions, e.g., Date.now() or Math.random()

Store

A store is an object that brings them together. A store has the following responsibilities:

It is important to note that you will only have a single store in a Redux application. If you want to split your data handling logic, you will use reducer composition instead of many stores.
import { createStore } from 'redux'
import todoApp from './reducers'
let store = createStore(todoApp)

Redux Tutorial With Example

We are going to take an example of a simple counter application using React.js and Redux. First, we need to setup a react environment.

Step 1:  Configure the project.

Create one project folder and in that create one file called package.json. Copy the following code into it.

{
  "name": "reduxapp",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "KRUNAL LATHIYA",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.24.0",
    "babel-loader": "^6.4.1",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-stage-3": "^6.22.0",
    "webpack": "^2.3.2",
    "webpack-dev-server": "^2.4.2"
  },
  "dependencies": {
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-redux": "^5.0.6",
    "redux": "^3.7.2"
  }
}

Switch to a terminal and type the following command.

npm install

Next step will be to create the webpack.config.js file in the root folder.

// webpack.config.js

module.exports = {
    entry: './src/main.js',
    output: {
        filename: 'bundle.js'
    },
    module: {
        loaders: [
            {
                loader: 'babel-loader',
                test: /\.js$/,
                exclude: /node_modules/
            }
        ]
    },
    devServer: {
        port: 3000
    }
};

Also, create one file called in root called .babelrc

{
  "presets": ["es2015", "react", "stage-3"]
}

Make one file in the root called index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Redux Tutorial 2017</title>
  </head>
  <body>
     <div id="root"></div>
  </body>
</html>

Go to a terminal and type this command.

npm start

Server will start at this URL: http://localhost:3000

Step 2: Create a main.js file inside src folder.

// main.js

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import App from './components/App';

render(
  <Provider>
    <App />
  </Provider>,
  document.getElementById('root')
)

I have included the react particular dependency, but also I have included react-redux. It provides us a store through our entire application. So our App element is wrapped around Provider.

Step 3: Create components directory inside src.

Make one directory and inside make our most important component file called App.js

// App.js

import React from 'react';

const App = () => {
 
 <div className="container">
   App Component
 </div>

}
export default App;

App.js the component where our other components are included. We are creating the simple counter application. However, we need to define first how many components are required to complete the application.

There are mainly two types of components when you are dealing with React and Redux.

  1. Smart Component
  2. Dumb Component

Smart Component

The smart component is the kind of component, which directly interacts with the state of our application. It has access to the store and it can either dispatch the actions or get the current state of our application. It is the smart components because when the store is changed, by default, it subscribes the new state and changes the view according to it. In our application, there are three smart components.

  1. Counter.js
  2. AddCounter.js
  3. RemoveCounter.js

All these smart components are put in the containers folder, which I will create later in this article.
Container components only contain that components that are smart.

Dumb Component

App.js is the Dumb component, it includes the child component but, it does not interact the store. So we put that component inside components folder.

Step 4: Create container dir. Inside src folder.

We need to create three container components inside this directory as I have mentioned before.

  1. We are creating AddCounter.js component
// AddComponent.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addCounter } from '../actions';
import { bindActionCreators } from 'redux';

class AddCounter extends Component {
  constructor(props) {
        super(props);
   }
   render() {
     return (
           <div className="container">
            <form>
              <div className="field is-grouped">
                <div className="control">
                  <button className="button is-primary" 
                    onClick={(e) => {e.preventDefault();this.props.dispatch(addCounter())}}>
                      Add
                  </button>
                </div>
              </div>
            </form>
            </div>
     )
   }
}
function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(addCounter, dispatch) }
}
export default connect(mapDispatchToProps)(AddCounter);

Here, I need to explain lots of things so let us get started.

If AddCounter component is container component, then it connects to the store remember, that is why it is a smart component.

So the last line of the code is that we are connecting our component to the Redux store.

When the user clicks the button according to Redux principle, it dispatches an action, so we need to pass dispatch function as a property to this component.

Now, it dispatches the action, and in our scenario, it named as addCounter(). So addCounter return an action.

Create an Action

Make one folder inside src called actions and in that create one file called index.js

// index.js

import * as actionType from './ActionType';

export const addCounter = () => ({
  type: actionType.ADD_COUNTER,
  payload: 1
});

So as I mentioned, It returns an object describes our actions.

Here, I have also included one more file called ActionType.js

This file is needed because all the action names are constant and if we create one file, which only exports the naming constant then it is easy for us to define any action without any typos because actions names are on the strings.

Make ActionType.js

This file is inside actions directory.

// ActionType.js

export const ADD_COUNTER = 'ADD_COUNTER';
export const REMOVE_COUNTER = 'REMOVE_COUNTER';

Now, coming to the point, we are at AddCounter.js file, right?

// AddCounter.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { addCounter } from '../actions';
import { bindActionCreators } from 'redux';

class AddCounter extends Component {
  constructor(props) {
        super(props);
      }
   render() {
     return (
           <div className="container">
            <form>
              <div className="field is-grouped">
                <div className="control">
                  <button className="button is-primary" 
                    onClick={(e) => {e.preventDefault();this.props.dispatch(addCounter())}}>
                      Add
                   </button>
                </div>
              </div>
            </form>
            </div>
     )
   }
}
function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(addCounter, dispatch) }
}
export default connect(mapDispatchToProps)(AddCounter);

Function mapDispatchToProps is needed because we need to pass dispatch as a property to our component and also we need to bind the actions with this component.

Step 5: Create reducer directory inside src and make one file

Make one file called counterReducer.js inside reducer directory.

// counterReducer.js

import * as actionType from '../actions/ActionType';

const counterReducer = (state = 0, action) => {
  let newState;
  switch (action.type) {
    case actionType.ADD_COUNTER:
      return newState = state + action.payload;
    case actionType.REMOVE_COUNTER:
      return newState = state - action.payload;
    default:
      return state
  }
}

export default counterReducer;

Please note that I have described both cases in here

  1. Increment (for add +1 in counter state)
  2. Decrement (decrease one from counter state)
If you carefully see the above cases then, I have not modified the state directly. See, I have defined a new variable and then assign new state in that variable and return that variable.
So, it is a pure function, which is not mutating any store state, just take the old state value and add that old value plus new value and assign it to the variable and return the new state of our application. This is the central principle of Redux after all.

Make one file inside reducer directory called index.js

// index.js

import { combineReducers } from 'redux';
import counterReducer from './counterReducer';

const counterApp = combineReducers({
  counterReducer
})

export default counterApp

Now, this is our single and final store. This is the store we include in our main.js file.

combineReducer function as the name suggests to combine all reducers in one store and return as a global application state object.
Now, our main.js file will look like this. I have passed the store to our entire application. Also Included the reducers.
// main.js

import React from 'react';
import { render } from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import App from './components/App';
import reducer from './reducers';

const store = createStore(reducer);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

Step 6: Create same smart component for RemoveCounter.js

Make RemoveCounter.js inside container directory.

// RemoveCounter.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { removeCounter } from '../actions';
import { bindActionCreators } from 'redux';

class RemoveCounter extends Component {
  constructor(props) {
    super(props);
  }
   render() {
     return (
           <div className="container">
            <form>
              <div className="field is-grouped">
                <div className="control">
                  <button className="button is-primary" 
                      onClick={(e) => {e.preventDefault();this.props.dispatch(removeCounter())}}>
                      Remove
                  </button>
                </div>
              </div>
            </form>
            </div>
     )
   }
}
function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(removeCounter, dispatch) }
}

export default connect(mapDispatchToProps)(RemoveCounter);

Now, switch to src  >>  actions  >>  index.js and add new action for removeCounter. So our final file looks like this.

// index.js

import * as actionType from './ActionType';

export const addCounter = () => ({
  type: actionType.ADD_COUNTER,
  payload: 1
});

export const removeCounter = () => ({
  type: actionType.REMOVE_COUNTER,
  payload: 1
});

We have already defined the decrement reducer.

// counterReducer.js

import * as actionType from '../actions/ActionType';

const counterReducer = (state = 0, action) => {
  let newState;
  switch (action.type) {
    case actionType.ADD_COUNTER:
      return newState = state + action.payload;
    case actionType.REMOVE_COUNTER:
      return newState = state - action.payload;
    default:
      return state
  }
}

export default counterReducer;

Step 7: Now final smart component remains is Counter.js

// Counter.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class Counter extends Component {
  constructor(props){
    super(props);
  }
  render(){
    return (
      <div className="cotainer">
        <div className="notification">
          <h1>
          {this.props.count}
          </h1>
        </div>
    </div>
    )
  }
}
function mapStateToProps(state){
  return {
    count: state.counterReducer,
  };
}
export default connect(mapStateToProps)(Counter);

This is the smart component, so we need to connect it with Redux store. So we have connected it with the store and fetched the latest state from the store and display it.

mapStateToProps maps the state to the props of current component and shows the data as a property of the component.

Step 8: Include all the components into the App.js file.

// App.js

import React from 'react';
import Counter from '../containers/Counter';
import AddCounter from '../containers/AddCounter';
import RemoveCounter from '../containers/RemoveCounter';

const App = () => {
  return (
    <div className="container">
      <Counter></Counter><br />
      <div className="columns">
        <div className="column is-11">
          <AddCounter></AddCounter>
        </div>
        <div className="column auto">
          <RemoveCounter></RemoveCounter>
        </div>
      </div>
      </div>
  )
}
export default App;

Finally, all the code is over, and if you have not started the development server, then please start via the following command.

npm start

If you switch to this URL: http://localhost:3000

 

react-redux tutorial 2017

Finally, our Redux Tutorial For Beginners With Example From Scratch is over. I have put this code on Github.

Fork Me On Github

Steps to use Github

  1. Clone the repository.
  2. Go to the project folder and type this command: npm install
  3. Start the development server by this command: npm start
  4. Switch to this URL: http://localhost:3000

 

If you have any doubt in React Redux Lession then ask in a comment below

The post Redux Tutorial With Example From Scratch appeared first on AppDividend.

]]>
https://appdividend.com/2017/08/23/redux-tutorial-example-scratch/feed/ 5