React – 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 React – AppDividend https://appdividend.com 32 32 React Material UI Example Tutorial https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/ https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/#comments Tue, 13 Nov 2018 10:05:13 +0000 http://localhost/wordpress/?p=2181 React Material UI Tutorial With Example From Scratch

React Material UI Example is today’s leading topic. It is the React components that implement Google’s Material Design. Material Design layouts encourage consistency across platforms, environments, and screen sizes by using uniform elements and spacing. Material-UI supports the latest and stable releases of across all the browsers and platforms. They also support Internet Explorer 11. You don’t need to […]

The post React Material UI Example Tutorial appeared first on AppDividend.

]]>
React Material UI Tutorial With Example From Scratch

React Material UI Example is today’s leading topic. It is the React components that implement Google’s Material Design. Material Design layouts encourage consistency across platforms, environments, and screen sizes by using uniform elements and spacing. Material-UI supports the latest and stable releases of across all the browsers and platforms. They also support Internet Explorer 11. You don’t need to provide any JavaScript polyfill as we manage unsupported browser features internally and in isolation. Let us take the React Material Example Tutorial From Scratch.

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.

React Material UI Example

Let us first install React.js using the following commands.

#1: Install React.js

npx create-react-app materialui
cd materialui
npm start

 

React Material UI Example

If you are facing any issue on compiling then, please create a .env file on the root and add the following line of code.

SKIP_PREFLIGHT_CHECK=true

#2: Install Material-UI

Type the following command to install Material-UI.

npm install @material-ui/core --save

# or

yarn add @material-ui/core

Now, modify the following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';

class App extends Component {
  render() {
    return (
      <Button variant="contained" color="primary">
        Welcome Material UI
      </Button>
    );
  }
}

export default App;

Save the file and go to the browser and you can see that we have successfully integrated the Material UI.

#SVG Icons

You can install the prebuild SVG icons using @material-ui/icons package.

npm install @material-ui/icons --save

# or

yarn add @material-ui/icons

#Fonts

You can include the stylesheets inside the index.html file.

<link rel="stylesheet"
  href=“https://fonts.googleapis.com/css?family=Roboto:400,500" />
<link rel="stylesheet"
  href=“https://fonts.googleapis.com/icon?family=Material+Icons" />

We can use the buttons as well as icons using the following code.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

class App extends Component {
  render() {
    return (
      <Button variant="outlined" color="primary">
        <Bookmarks></Bookmarks>
          Chaper 2
      </Button>
    );
  }
}

export default App;

You can use material.io/tools/icons to find a specific icon. When importing an icon, keep in mind that the names of the icons are PascalCase.

Notable props for the Button component include:

  • variant: The visual style of the component, either containedoutlined, fab, or empty for the default link-style.
  • color: One of primarysecondary, or default, which is the same color as if it’s left empty. We’ll cover the customization of these colors later.
  • mini: If the variant is set to fab (floating action button), then the size of the button is reduced.

#Navbar

Let us create a component inside the src folder called Navbar.js and add the following code.

// Navbar.js

import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';

const NavBar = () => {
    return(
        <div>
        <AppBar position="static">
            <Toolbar>
                React Material UI Example
            </Toolbar>
        </AppBar>
        </div>
    )
}
export default NavBar;

Now, import Navbar.js component inside the App.js component.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import Navbar from './Navbar';
class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button>
      </div>
    );
  }
}

export default App;

Now, you can see that we have implemented the basic design of the Navigation bar.

#TextField

Add a following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import TextField from '@material-ui/core/TextField';
import Navbar from './Navbar';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button> <br />
        <TextField
          placeholder="Placeholder here"
          label="Basic TextField" />
      </div>
    );
  }
}

export default App;

Save the file, and you can see the textbox. The TextField, we have imported from @material-ui/core/TextField, behaves like the standard React input component.

#Cards

Create one file called Card.js inside the src folder. Add the following code inside the Card.js file.

// Card.js

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import IMG from './MZ.png';

const styles = {
  card: {
    maxWidth: 345,
  },
  media: {
    height: 140,
  },
};

function MediaCard(props) {
  const { classes } = props;
  return (
    <Card className={classes.card}>
      <CardActionArea>
        <CardMedia
          className={classes.media}
          image= {IMG}
          title="Contemplative Reptile"
        />
        <CardContent>
          <Typography gutterBottom variant="h5" component="h2">
            Zukerberg
          </Typography>
          <Typography component="p">
            Lizards are a widespread group of squamate reptiles, with over 6,000 species, ranging
            across all continents except Antarctica
          </Typography>
        </CardContent>
      </CardActionArea>
      <CardActions>
        <Button size="small" color="primary">
          Share
        </Button>
        <Button size="small" color="primary">
          Learn More
        </Button>
      </CardActions>
    </Card>
  );
}

MediaCard.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(MediaCard);

Save the file and import the Card.js file inside the App.js file.

// App.js

import React, { Component } from 'react';
import Button from '@material-ui/core/Button';
import Bookmarks from '@material-ui/icons/Bookmarks';

import TextField from '@material-ui/core/TextField';
import Navbar from './Navbar';
import MediaCard from './Card';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
        <Button variant="outlined" color="primary">
          <Bookmarks></Bookmarks>
        </Button> <br />
        <TextField
          placeholder="Placeholder here"
          label="Basic TextField" />
        <MediaCard />
      </div>
    );
  }
}

export default App;

#Theming

Material-UI uses the JavaScript-based approach to theming its components called CSS-in-JS. With the help of this approach, CSS classnames are generated using JavaScript objects. 

To pass the styles object into our component, we will use the withStyles function to return the higher-order component that gives our classnames as a prop called classes.

const MyComponent = (props) => {
  const classes = props.classes;
  return (
    <div className={classes.container}>
      // stuff
    </div>
  );
}

export default withStyles(styles)(MyComponent);

Creating the custom theme

To create a custom theme, use a createMuiTheme function and pass its return value to a MuiThemeProvider element at root of your App.

import { createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';

const theme = createMuiTheme();

const App = props => (
  <MuiThemeProvider theme={theme}>
    // your app
  </MuiThemeProvider>
);

Now, all children of a MuiThemeProvider have the uniformly customizable style!

createMuiTheme function usually takes the object to define a theme:

const theme = createMuiTheme({
  palette: {
    primary: '#e89eef',
    secondary: '#336b87'
  }
});

All colors, including a primary and the secondary colors we used earlier in the tutorial, are all themeable. The full range of options can be found in the official theming documentation. Material-UI is a great way to add the polished look and feel to the controls of your React web application with little effort.

Finally, React Material UI Example Tutorial is over.

 

The post React Material UI Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/13/react-material-ui-example-tutorial/feed/ 3
React CRUD Example | MERN Stack Tutorial https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/ https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/#comments Sun, 11 Nov 2018 20:23:48 +0000 http://localhost/wordpress/?p=2141 React CRUD Example Tutorial From Scratch

React CRUD Example | MERN Stack Tutorial is today’s leading topic. This article’s goal is to explain the by making the CRUD application. Most applications are CRUD applications. If you don’t know what CRUD is, it’s short for Create, Read, Update and Delete. This application is also called a MERN Stack application because we are using MongoDB, Express, […]

The post React CRUD Example | MERN Stack Tutorial appeared first on AppDividend.

]]>
React CRUD Example Tutorial From Scratch

React CRUD Example | MERN Stack Tutorial is today’s leading topic. This article’s goal is to explain the by making the CRUD application. Most applications are CRUD applications. If you don’t know what CRUD is, it’s short for Create, Read, Update and Delete. This application is also called a MERN Stack application because we are using MongoDB, Express, React, and Node.js tech stack. This article will show you the steps to create an app where the user can create new business, fetch that business, edit business and delete business using React.js. Let us understand the basics of React.js.

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.

What is React?

React.js is UI Library and not a complete Framework like Angular. React is the JavaScript library for building user interfaces. It is maintained by Facebook, Instagram and a community of individual developers and corporations. You can find its official documentation here.

Why use React?

React.js allows you to express how your app should look at any given point in time. React will automatically manage all UI updates when your underlying data changes. When the data changes, React conceptually hits the “refresh” button and knows to only update the changed parts. The main reason to use React for your next project is following.

  1. Fast Learning Curve.
  2. Reusable Components.
  3. Fast render with Virtual DOM.
  4. Clean Abstraction.
  5. Redux: A State Management Library For Complex UIs.
  6. Great Developer Tools.
  7. React Native: You can build a cross-platform native mobile application for Android or iOS.

Who uses React?

Aside from Facebook and Instagram, many well-known companies use React including Dropbox, PayPal, Netflix, Airbnb and many more.

MERN Stack Tutorial

We will use the following Technologies with its version.

  1. MacOS (Mojave)
  2. Node v10.11.0
  3. NPM v6.4.1
  4. MongoDB shell version v3.6.3
  5. MongoDB version v3.6.3
  6. React.js version 16.6.1

React CRUD Example

Create a new React app using the following command.

#1: Install React Application

npx create-react-app reactcrud
cd reactcrud
npm start

 

React CRUD Example

If you are facing any issue on compiling then, please create a .env file on the root and add the following line of code.

SKIP_PREFLIGHT_CHECK=true

Go to this URL: http://localhost:3000/

 

MERN Stack Tutorial

Now, install the Bootstrap 4 Framework using the following command.

yarn add bootstrap

# or

npm install bootstrap --save

Import the Bootstrap CSS Framework inside our project.

Modify the code inside the src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div className="container">
        <h2>React CRUD Tutorial</h2>
      </div>
    );
  }
}

export default App;

Save the file and go to the browser and you can see that we have successfully integrated bootstrap 4 in our react application.

#2: Configure React routing

Type the following command to install the react- router-dom module. If you want to find more information about the react-router-dom module, then you can follow this documentation.

yarn add react-router-dom

# or

npm install react-router-dom --save

Go to the index.js file and Wrap the BrowserRouter object around the App.js component.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import App from './App';
import * as serviceWorker from './serviceWorker';

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

serviceWorker.unregister();

Now, create three components.

Inside the src folder, create one directory called components and inside that folder, make three components.

  1. create.component.js
  2. edit.component.js
  3. index.component.js
// create.component.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Create Component!!</p>
            </div>
        )
    }
}
// edit.component.js

import React, { Component } from 'react';

export default class Edit extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Edit Component!!</p>
            </div>
        )
    }
}
// index.component.js

import React, { Component } from 'react';

export default class Index extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Index Component!!</p>
            </div>
        )
    }
}

Now, add the navigation bar in our React CRUD example. Write a following code inside the App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';

import Create from './components/create.component';
import Edit from './components/edit.component';
import Index from './components/index.component';

class App extends Component {
  render() {
    return (
      <Router>
        <div className="container">
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <Link to={'/'} className="navbar-brand">React CRUD Example</Link>
            <div className="collapse navbar-collapse" id="navbarSupportedContent">
              <ul className="navbar-nav mr-auto">
              <li className="nav-item">
                  <Link to={'/'} className="nav-link">Home</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/create'} className="nav-link">Create</Link>
                </li>
                <li className="nav-item">
                  <Link to={'/index'} className="nav-link">Index</Link>
                </li>
              </ul>
            </div>
          </nav> <br/>
          <h2>Welcome to React CRUD Tutorial</h2> <br/>
          <Switch>
              <Route exact path='/create' component={ Create } />
              <Route path='/edit/:id' component={ Edit } />
              <Route path='/index' component={ Index } />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Save the file and go to the browser.

 

React CRUD Tutorial

#3: Create the bootstrap form

Write the code to generate the bootstrap form inside the create.component.js file.

// create.component.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div style={{marginTop: 10}}>
                <h3>Add New Business</h3>
                <form>
                    <div className="form-group">
                        <label>Add Person Name:  </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add Business Name: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add GST Number: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Register Business" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

 

MERN Stack Example

#4: Submit the Form

Okay, now we have three fields.

  1. person name
  2. business name
  3. gst number

So we need to create four functions that can track the values of the textbox and set that state according to it. Also, the fourth function will send the POST request to the node express server.

Now, first, we will define the constructor and set the initial state and then also bind this to the different events inside the constructor.

Then define the different functions with each input text values. So when the user types inside the textbox, we set the state according to it.

So, let say, the user is typing the person name inside the textbox, we are changing the state value of person name. Finally, same for all of the inputs and when we submit the form, we get the values from the state and send to the POST request.

// App.js

import React, { Component } from 'react';

export default class Create extends Component {
  constructor(props) {
      super(props);
      this.onChangePersonName = this.onChangePersonName.bind(this);
      this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
      this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
      this.onSubmit = this.onSubmit.bind(this);

      this.state = {
          person_name: '',
          business_name: '',
          business_gst_number:''
      }
  }
  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    console.log(`The values are ${this.state.person_name}, ${this.state.business_name}, and ${this.state.business_gst_number}`)
    this.setState({
      person_name: '',
      business_name: '',
      business_gst_number: ''
    })
  }
 
  render() {
      return (
          <div style={{ marginTop: 10 }}>
              <h3>Add New Business</h3>
              <form onSubmit={this.onSubmit}>
                  <div className="form-group">
                      <label>Person Name:  </label>
                      <input 
                        type="text" 
                        className="form-control" 
                        value={this.state.person_name}
                        onChange={this.onChangePersonName}
                        />
                  </div>
                  <div className="form-group">
                      <label>Business Name: </label>
                      <input type="text" 
                        className="form-control"
                        value={this.state.business_name}
                        onChange={this.onChangeBusinessName}
                        />
                  </div>
                  <div className="form-group">
                      <label>GST Number: </label>
                      <input type="text" 
                        className="form-control"
                        value={this.state.business_gst_number}
                        onChange={this.onChangeGstNumber}
                        />
                  </div>
                  <div className="form-group">
                      <input type="submit" value="Register Business" className="btn btn-primary"/>
                  </div>
              </form>
          </div>
      )
  }
}

#5: Create a backend on Node.js

Inside our reactcrud project root, create one folder called api and go inside that folder and initialize the package.json file.

npm init -y

Now, install the following node.js dependencies.

yarn add express body-parser cors mongoose

# or

npm install express body-parser cors mongoose --save

Also, install the nodemon as a development dependency. So that we do not need to restart every time, we change our server code.

npm install nodemon --save-dev

Now, inside the api folder, create one file called the server.js and add the following code inside it.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file and open a new tab terminal inside the api folder and hit the following command to spin up the node.js server.

nodemon server

You can see inside the terminal that, our node.js server is running.

React CRUD Example | MERN Stack Tutorial

 

#6: Setup a MongoDB database

If you are a beginner in MongoDB database, then please check out by below tutorial.

Related Post: NoSQL MongoDB Tutorial

I have already installed the MongoDB on Mac. So I am starting the MongoDB server by the following command.

mongod

Inside the api folder, create one file called the DB.js and add the following line of code.

// DB.js

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

In my local MongoDB database, the username and password are empty, but in the production, you need to create one admin user and assign the database to that user.

Now, import this DB.js file into the server.js file.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');

mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
  () => {console.log('Database is connected') },
  err => { console.log('Can not connect to the database'+ err)}
);

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file, and you can see inside the terminal that our node.js application is connected to a mongodb database.

#7: Create a Mongoose Schema

Next step is that we need to create a schema for the mongodb database. For that, create a file inside the api project root called business.model.js and add the following code.

// business.model.js

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

// Define collection and schema for Business
let Business = new Schema({
  person_name: {
    type: String
  },
  business_name: {
    type: String
  },
  business_gst_number: {
    type: Number
  }
},{
    collection: 'business'
});

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

We have taken three fields called person_name, business_name, and business_gst_number with its datatypes.

#8: Define the route for Node.js Express application

Write the CRUD code inside the business.route.js file.

// business.route.js

const express = require('express');
const businessRoutes = express.Router();

// Require Business model in our routes module
let Business = require('./business.model');

// Defined store route
businessRoutes.route('/add').post(function (req, res) {
  let business = new Business(req.body);
  business.save()
    .then(business => {
      res.status(200).json({'business': 'business in added successfully'});
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

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

// Defined edit route
businessRoutes.route('/edit/:id').get(function (req, res) {
  let id = req.params.id;
  Business.findById(id, function (err, business){
      res.json(business);
  });
});

//  Defined update route
businessRoutes.route('/update/:id').post(function (req, res) {
    Business.findById(req.params.id, function(err, business) {
    if (!business)
      res.status(404).send("data is not found");
    else {
        business.person_name = req.body.person_name;
        business.business_name = req.body.business_name;
        business.business_gst_number = req.body.business_gst_number;

        business.save().then(business => {
          res.json('Update complete');
      })
      .catch(err => {
            res.status(400).send("unable to update the database");
      });
    }
  });
});

// Defined delete | remove | destroy route
businessRoutes.route('/delete/:id').get(function (req, res) {
    Business.findByIdAndRemove({_id: req.params.id}, function(err, business){
        if(err) res.json(err);
        else res.json('Successfully removed');
    });
});

module.exports = businessRoutes;

Here, we have defined the CRUD operations for MongoDB. So when the request hits the server, it maps the URI and according to URI, the above function will be executed, and database operation will be performed and send the response to the client.

Here, we have used a Mongoose ORM to save, update, delete the data from the database. Mongoose is an ORM used in MongoDB database. Now, we have all the CRUD operations set up on the route file; we need to import inside the server.js file.

So, our final server.js file looks like this.

// server.js

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');
const businessRoute = require('./business.route');

mongoose.Promise = global.Promise;
mongoose.connect(config.DB, { useNewUrlParser: true }).then(
  () => {console.log('Database is connected') },
  err => { console.log('Can not connect to the database'+ err)}
);

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/business', businessRoute);

app.listen(PORT, function(){
  console.log('Server is running on Port:',PORT);
});

Save the file and see the terminal and check if we got any errors.

#9: Install Axios library and send a POST request.

Install the Axios library and send the POST request. If you want to learn about the Axios library, then check out my Getting Started With Axios Promise Based HTTP Client Tutorial Example article.

yarn add axios

# or

npm install axios --save

Now, send the HTTP POST request along with the form data to the node js server. We will send the data as an object because we have used the body-parser at the backend to pluck the data from the request and save it in the database.

Write the following code inside the create.component.js file.

// create.component.js

import React, { Component } from 'react';
import axios from 'axios';

export default class Create extends Component {
  constructor(props) {
    super(props);
    this.onChangePersonName = this.onChangePersonName.bind(this);
    this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
    this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state = {
      person_name: '',
      business_name: '',
      business_gst_number:''
    }
  }
  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    const obj = {
      person_name: this.state.person_name,
      business_name: this.state.business_name,
      business_gst_number: this.state.business_gst_number
    };
    axios.post('http://localhost:4000/business/add', obj)
        .then(res => console.log(res.data));
    
    this.setState({
      person_name: '',
      business_name: '',
      business_gst_number: ''
    })
  }
 
  render() {
    return (
        <div style={{ marginTop: 10 }}>
            <h3>Add New Business</h3>
            <form onSubmit={this.onSubmit}>
                <div className="form-group">
                    <label>Person Name:  </label>
                    <input 
                      type="text" 
                      className="form-control" 
                      value={this.state.person_name}
                      onChange={this.onChangePersonName}
                      />
                </div>
                <div className="form-group">
                    <label>Business Name: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_name}
                      onChange={this.onChangeBusinessName}
                      />
                </div>
                <div className="form-group">
                    <label>GST Number: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_gst_number}
                      onChange={this.onChangeGstNumber}
                      />
                </div>
                <div className="form-group">
                    <input type="submit" value="Register Business" className="btn btn-primary"/>
                </div>
            </form>
        </div>
    )
  }
}

Now, submit the form with proper values and open your browser console panel and see the response.

 

React CRUD Project

Also, now check inside the mongodb database and see the values.

To see the values inside the database, we can start a mongoshell and look at the values in the database.

 

Mongo CRUD

So, we can see that our data is added successfully.

#10: Display the backend data

Write the following code inside the index.component.js file.

// index.component.js

import React, { Component } from 'react';
import axios from 'axios';
import TableRow from './TableRow';

export default class Index extends Component {

  constructor(props) {
      super(props);
      this.state = {business: []};
    }
    componentDidMount(){
      axios.get('http://localhost:4000/business')
        .then(response => {
          this.setState({ business: response.data });
        })
        .catch(function (error) {
          console.log(error);
        })
    }
    tabRow(){
      return this.state.business.map(function(object, i){
          return <TableRow obj={object} key={i} />;
      });
    }

    render() {
      return (
        <div>
          <h3 align="center">Business List</h3>
          <table className="table table-striped" style={{ marginTop: 20 }}>
            <thead>
              <tr>
                <th>Person</th>
                <th>Business</th>
                <th>GST Number</th>
                <th colSpan="2">Action</th>
              </tr>
            </thead>
            <tbody>
              { this.tabRow() }
            </tbody>
          </table>
        </div>
      );
    }
  }

So, here, we have sent the GET request to the node.js server and fetch that data from an API.

We have imported the TableRow.js component. So let us create that component. Inside the components folder, create one more component called TableRow.js and add the following code inside it.

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.person_name}
          </td>
          <td>
            {this.props.obj.business_name}
          </td>
          <td>
            {this.props.obj.business_gst_number}
          </td>
          <td>
            <button className="btn btn-primary">Edit</button>
          </td>
          <td>
            <button className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

This component is responsible for display the row data fetched from the backend.

Save the file and go to the browser and see this URL: http://localhost:3000/index.

 

React Node Example

#11: Edit and Update Functionality

First, add the Link to the TableRow.js file.

// TableRow.js

import { Link } from 'react-router-dom';

<Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>

Add the following code to the edit.component.js file.

// edit.component.js

import React, { Component } from 'react';
import axios from 'axios';

export default class Edit extends Component {
  constructor(props) {
    super(props);
    this.onChangePersonName = this.onChangePersonName.bind(this);
    this.onChangeBusinessName = this.onChangeBusinessName.bind(this);
    this.onChangeGstNumber = this.onChangeGstNumber.bind(this);
    this.onSubmit = this.onSubmit.bind(this);

    this.state = {
      person_name: '',
      business_name: '',
      business_gst_number:''
    }
  }

  componentDidMount() {
      axios.get('http://localhost:4000/business/edit/'+this.props.match.params.id)
          .then(response => {
              this.setState({ 
                person_name: response.data.person_name, 
                business_name: response.data.business_name,
                business_gst_number: response.data.business_gst_number });
          })
          .catch(function (error) {
              console.log(error);
          })
    }

  onChangePersonName(e) {
    this.setState({
      person_name: e.target.value
    });
  }
  onChangeBusinessName(e) {
    this.setState({
      business_name: e.target.value
    })  
  }
  onChangeGstNumber(e) {
    this.setState({
      business_gst_number: e.target.value
    })
  }

  onSubmit(e) {
    e.preventDefault();
    const obj = {
      person_name: this.state.person_name,
      business_name: this.state.business_name,
      business_gst_number: this.state.business_gst_number
    };
    axios.post('http://localhost:4000/business/update/'+this.props.match.params.id, obj)
        .then(res => console.log(res.data));
    
    this.props.history.push('/index');
  }
 
  render() {
    return (
        <div style={{ marginTop: 10 }}>
            <h3 align="center">Update Business</h3>
            <form onSubmit={this.onSubmit}>
                <div className="form-group">
                    <label>Person Name:  </label>
                    <input 
                      type="text" 
                      className="form-control" 
                      value={this.state.person_name}
                      onChange={this.onChangePersonName}
                      />
                </div>
                <div className="form-group">
                    <label>Business Name: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_name}
                      onChange={this.onChangeBusinessName}
                      />
                </div>
                <div className="form-group">
                    <label>GST Number: </label>
                    <input type="text" 
                      className="form-control"
                      value={this.state.business_gst_number}
                      onChange={this.onChangeGstNumber}
                      />
                </div>
                <div className="form-group">
                    <input type="submit" 
                      value="Update Business" 
                      className="btn btn-primary"/>
                </div>
            </form>
        </div>
    )
  }
}

So, what we have done is, we have used the component lifecycle method to fetch the data from the API.

That data needs to be displayed inside the textbox because this is edit form. Next, it is the same thing as we have written the code in the create.component.js file.

Save the file and go to the edit page from the index or listing page. If the data is not displayed then please first check that you have the running node.js server on the backend.

 

React MongoDB Example

We have also written the code that will update the data because we have written the function that will send the request to the node.js server and update the data based on the ID.

#12: Delete the data

Now, the only thing remaining is to delete the data. So define the delete function inside TableRow.js file.

// TableRow.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';

class TableRow extends Component {

  constructor(props) {
        super(props);
        this.delete = this.delete.bind(this);
    }
    delete() {
        axios.get('http://localhost:4000/business/delete/'+this.props.obj._id)
            .then(console.log('Deleted'))
            .catch(err => console.log(err))
    }
  render() {
    return (
        <tr>
          <td>
            {this.props.obj.person_name}
          </td>
          <td>
            {this.props.obj.business_name}
          </td>
          <td>
            {this.props.obj.business_gst_number}
          </td>
          <td>
            <Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>
          </td>
          <td>
            <button onClick={this.delete} className="btn btn-danger">Delete</button>
          </td>
        </tr>
    );
  }
}

export default TableRow;

Now, we have completed React CRUD Example or MERN Stack Tutorial From Scratch.

I have put this code on Github. So you can check that code as well.

Finally, React CRUD Example Tutorial is over. Thanks for taking.

Github Code

The post React CRUD Example | MERN Stack Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/11/react-crud-example-mern-stack-tutorial/feed/ 34
React Context API Tutorial With Example https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/ https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/#respond Sat, 03 Nov 2018 21:22:50 +0000 http://localhost/wordpress/?p=2067 React Context API Example Tutorial

React Context API Tutorial With Example is today’s leading topic.  Context provides the way to pass data through the component tree without having to pass the props down manually at every level. In the typical React application, data is passed top-down (parent to child) via props, but this can be the cumbersome and not good idea for certain […]

The post React Context API Tutorial With Example appeared first on AppDividend.

]]>
React Context API Example Tutorial

React Context API Tutorial With Example is today’s leading topic.  Context provides the way to pass data through the component tree without having to pass the props down manually at every level. In the typical React application, data is passed top-down (parent to child) via props, but this can be the cumbersome and not good idea for certain types of props (e.g., locale preference, theme) that are required by many components within the application. The React team suggests sticking to props if you have just a few levels of children to pass because it’s still a much less complicated API than the Context API.

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.

React Context API Tutorial With Example

Create a new React app using the following command.

npx create-react-app contextapi
cd contextapi
npm start

 

React Context API Tutorial With Example

When you start the react development server and find any error regarding webpack-dev-server then you will find a solution in the terminal, if it works for you then best otherwise you can go for the below solution.

Create one .env file in root and add the following code inside it.

SKIP_PREFLIGHT_CHECK=true

Install the bootstrap 4 css framework also by the following command.

yarn add bootstrap

# or

npm install bootstrap

You create the context using React.createContext() , which returns the Context object.

const {Provider, Consumer} = React.createContext()

Then you create the wrapper component that returns the Provider component, and you add as children all the elements from which you want to access the context. Let us take an example.

Write the following code inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

const BtnColorContext = React.createContext('btn btn-dark');

class App extends Component {
  render() {
    return (
      <BtnColorContext.Provider value="btn btn-info">
        <Button />
      </BtnColorContext.Provider>
    );
  }
}

function Button(props) {
  return (
  <div className="container">
    <ThemedButton />    
  </div>
  );
}

class ThemedButton extends Component {
  
  static contextType = BtnColorContext;
  render() {
    return <button className={this.context} >
      hello
    </button>;
  }
}

export default App;

You can see in the webpage output that the color of the button is changed according to btn btn-info.

Explanation of React Context API

Context is designed to share the data that can be considered as a “global” for the tree of React components, such as a current authenticated user, theme, or preferred language settings. We have done the following things in the above example. Let us see one by one.

First, we create a button class context and assign the btn btn-dark. 

Then inside the App class, we have changed the value of the context to the btn btn-info.

Now, the inside the App component, the nested component is Button. It is a stateless component, means just a functional component, which receives the props as an argument.

Now, inside that component, we have one more nested component called ThemedButton. But we have not passed any property from Button component to ThemedButton.

So, now if we want to access the value of the button class, which we have defined in the React context, then we need to write the following code inside ThemedButton class.

class ThemedButton extends Component {
  
  static contextType = BtnColorContext;
  render() {
    return <button className={this.context} >
      hello
    </button>;
  }
}

So, we have defined the static contextType and use the current context value by this.context, and now we can see the latest context value, which is described in this code.

<BtnColorContext.Provider value="btn btn-info">
   <Button />
</BtnColorContext.Provider>

Now, if we write the above code like this then see the output on the result.

<div>
  <Button />
</div>

Save the file and see the button color. It will change to dark according to defined the react context. That means, if we modify the context in between parent to children flow then it will take the latest value otherwise it will take the first defined value.

React Context API

1. React.createContext

You can create the context using the following syntax.

const MyContext = React.createContext(defaultValue);

Creates a Context object. When React renders the component that subscribes to this Context object, it will read the current context value from a closest matching Provider above it in the tree. We have used this in our example to change the button class from dark to info.

The defaultValue argument is only used when the component does not have the matching Provider above it in the tree. It is very helpful for testing components in the isolation without wrapping them. Please Note here that passing undefined as a Provider value does not cause consuming components to use defaultValue.

2. Context.Provider

The syntax is following.

<MyContext.Provider value={/* some value */}>

Every Context object comes with the Provider React component that allows consuming components to subscribe to the context changes. Accepts the value prop to be passed to the consuming components that are the descendants of this Provider. One Provider can be connected to the many consumers. Providers can be nested to override the values deeper within a tree. As we have overridden the default value of the className and we get the latest value of the className in the component tree.

3. Context.Consumer

The syntax is following.

<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>

It is the React component that subscribes to the context changes. It lets us subscribe to the context within the function component. Requires the function as a child

The function receives a current context value and returns the React node. The value argument passed to a function will be equal to a value prop of the closest Provider for this context above in the tree. If there are no Providers for the context above, the value argument will be equal to the defaultValue that was passed to createContext().

Finally, React Context API Tutorial With Example is over.

The post React Context API Tutorial With Example appeared first on AppDividend.

]]>
https://appdividend.com/2018/11/03/react-context-api-tutorial-with-example/feed/ 0
React Dropdown Select Example Tutorial https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/ https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/#respond Fri, 19 Oct 2018 10:29:18 +0000 http://localhost/wordpress/?p=1948 React Multiple Dropdown Example

React Dropdown Select Example Tutorial is the today’s leading topic. We use the library called React-select that features dynamic search/filter, async option loading, accessibility, and fast render times. It has a flexible and beautiful Select Input control for ReactJS with multi-select, autocomplete and ajax support. It has the following features. Flexible approach to data, with customizable functions. Extensible styling […]

The post React Dropdown Select Example Tutorial appeared first on AppDividend.

]]>
React Multiple Dropdown Example

React Dropdown Select Example Tutorial is the today’s leading topic. We use the library called React-select that features dynamic search/filter, async option loading, accessibility, and fast render times. It has a flexible and beautiful Select Input control for ReactJS with multi-select, autocomplete and ajax support.

It has the following features.

  • Flexible approach to data, with customizable functions.
  • Extensible styling API with emotion.
  • Component Injection API for complete control over the UI behavior.
  • Controllable state props and modular architecture.
  • Long-requested features like option groups, portal support, animation, and more.
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.

React Dropdown Select Example Tutorial

First, we install the React.js and then install the react-select library.

#1: Install React and other libraries

Type the following command.

npx create-react-app reaselect

 

React Dropdown Select Example Tutorial

Now, go inside the project folder.

Earn a Tech Degree and get the skills like Frontend Development or Javascript Development that can help you to launch a career. Start your free trial
cd reaselect

To install React-Select v2, add the react-select package using the following command.

yarn add react-select

# or

npm install react-select --save

Also, we can install the Bootstrap 4 using the following command.

yarn add bootstrap

# or

npm install bootstrap --save

#2: Import the react-select module.

Inside the src >> App.js file, add the following code.

// App.js

import React from 'react';
import Select from 'react-select';
import 'bootstrap/dist/css/bootstrap.min.css';

const techCompanies = [
  { label: "Apple", value: 1 },
  { label: "Facebook", value: 2 },
  { label: "Netflix", value: 3 },
  { label: "Tesla", value: 4 },
  { label: "Amazon", value: 5 },
  { label: "Alphabet", value: 6 },
];

const App = () => (
  <div className="container">
    <div className="row">
      <div className="col-md-4"></div>
      <div className="col-md-4">
        <Select options={ techCompanies } />
      </div>
      <div className="col-md-4"></div>
    </div>
  </div>
);

export default App

 

React Select Dropdown example

Here, we have imported the bootstrap 4 and react-select library.

Then, we have created an Array that contains the data that needs to be displayed on the drop down.

After that, we have used the Select element and pass the options object. There are many other properties available which are the following.

  • autofocus – focus the control when it mounts.
  • className – apply a className to the control.
  • classNamePrefix – apply classNames to inner elements with the given prefix.
  • isDisabled – disable the control.
  • isMulti – allow the user to select multiple values.
  • isSearchable – allow the user to search for matching options.
  • name – generate an HTML input with this name, containing the current value.
  • onChange – subscribe to change events.
  • options – specify the options the user can select from.
  • placeholder – change the text displayed when no option is selected.
  • value – control the current value.

You must import the Select component from react-select.

Each object in the options array techCompanies must have at least two values: label, a string, and value, which may be any type.

The only required prop is the options array.

#Other Features

We can use the multiple select using the following property. We need to add that property.

<Select options={ techCompanies } 
          isMulti />

 

React Multi Select Example

Controllable Props

You can control the following props by providing values for them. If you don’t, react-select will manage them for you.

  • value / onChange – specify the current value of the control.
  • menuIsOpen / onMenuOpen / onMenuClose – control whether the menu is open.
  • inputValue / onInputChange – control the value of the search input (changing this will update the available options).

If you don’t provide these props, you can set the initial value of the state they control:

  • defaultValue – set the initial value of the control.
  • defaultMenuIsOpen – set the initial open value of the menu.
  • defaultInputValue – set the initial value of the search input.

Methods

React-select exposes two public methods:

  • focus() – focus the control programmatically.
  • blur() – blur the control programmatically.

Finally, React Dropdown Select Example Tutorial is over.

The post React Dropdown Select Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/10/19/react-dropdown-select-example-tutorial/feed/ 0
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 Redux Node MongoDB JWT Authentication Example https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/ https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/#comments Wed, 18 Jul 2018 11:42:45 +0000 http://localhost/wordpress/?p=1327 Redux JWT Authentication Example Tutorial

React Redux Node MongoDB JWT Authentication Example is the today’s leading topic. We use React and Redux for the frontend, Node.js as a platform, express as a web framework and MongoDB as a NoSQL database. We use JWT authentication where, if the user is logged in then it returns a token and the client saves that […]

The post React Redux Node MongoDB JWT Authentication Example appeared first on AppDividend.

]]>
Redux JWT Authentication Example Tutorial

React Redux Node MongoDB JWT Authentication Example is the today’s leading topic. We use React and Redux for the frontend, Node.js as a platform, express as a web framework and MongoDB as a NoSQL database. We use JWT authentication where, if the user is logged in then it returns a token and the client saves that token. The client uses that token each time when he tries to access the protected route. So the concept is obvious. Now let us start this small project. This article is not about the beginner’s course. So if you are not familiar with Redux with React then check out this post React Redux Axios Tutorial Example From Scratch.

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)

React Redux Node MongoDB JWT Authentication

Now for this project, we need to separate projects.

  1. React Frontend
  2. Node Backend

For React Frontend, we can use the create-react-app boilerplate to kick off the frontend project, but for the backend, we need to create the project from scratch.

#1: Create a backend on Node.js.

Now, first, we need to create the main project. So type the following command to create a project.

mkdir jwtauth

Now, go inside that folder.

cd jwtauth

In this folder, we have two more folders. One for backend and one for the frontend.

Create a backend folder.

mkdir backend

Now, go into the folder.

cd backend

Type the following command to initialize the package.json file.

npm init -y

Okay, now we need to install the dependencies. I have installed all the dependencies that will need in this backend project. We will use a passport, passport-jwt, jsonwebtoken for authentication. Mongoose for ORM for MongoDB, the validator for validating the input types, body-parser for parsing the data that comes from request, gravatar for getting avatar image associated with an email address.

yarn add bcryptjs body-parser express gravatar jsonwebtoken mongoose passport passport-jwt validator

# or

npm install --save bcryptjs body-parser express gravatar jsonwebtoken mongoose passport passport-jwt validator

Also, we need to install nodemon for development dependency.

npm install -D nodemon

We need this dependency because when we save our file, we need to restart the node.js server and nodemon does this precisely without stop or restart the server manually.

Okay, now start the mongodb server by the following command.

mongod

If you have not installed then install MongoDB server first and then if possible install the database client like studio3t or use MongoLab to create a database. It has the free version.

#2: Create an app.js file to create the node server.

Inside the backend folder, create one file called app.js and add the following code.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

Go to the root of the backend project and open the terminal and type the following command to start the node.js server by using the following command.

nodemon app

It will start the server at port: 5000.

React Redux Node MongoDB JWT Authentication Example

 

#3: Create a database file called db.js.

Write the following code inside the db.js file.

// db.js

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

Include the db.js file inside an app.js file.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const config = require('./db');

mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
);

const app = express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

Save the file and make sure that your mongodb server is running. So in the console, you can see that Database is connected!!

#4: Create a User model.

Inside the backend folder, create one folder called models and inside that folder, create one file called User.js. Write the following schema inside User.js file.

// User.js

const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const UserSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true
    },
    avatar: {
        type: String
    },
    date: {
        type: Date,
        default: Date.now
    }
});

const User = mongoose.model('users', UserSchema);

module.exports = User;

The name, email, and password come from the React.js form. We fetch the avatar from gravatar based on email address.

#5: Create a validation for input values.

Inside the backend folder, create a folder called validation and inside that, create one file called register.js. But before that, we also need to create one more validation file called is-empty.js inside same validation directory.

// is-empty.js

const isEmpty = (value) => {
    return (
        value === undefined ||
        value === null ||
        (typeof value === 'object' && Object.keys(value).length === 0) ||
        (typeof value === 'string' && value.trim().length === 0)
    );
}
module.exports = isEmpty;

This function will check if the passed value is undefined or null or object or string‘s length is 0.

Write the following code inside the register.js file. For validation, we have used the validator library.

// register.js

const Validator = require('validator');
const isEmpty = require('./is-empty');

module.exports = function validateRegisterInput(data) {
    let errors = {};
    data.name = !isEmpty(data.name) ? data.name : '';
    data.email = !isEmpty(data.email) ? data.email : '';
    data.password = !isEmpty(data.password) ? data.password : '';
    data.password_confirm = !isEmpty(data.password_confirm) ? data.password_confirm : '';

    if(!Validator.isLength(data.name, { min: 2, max: 30 })) {
        errors.name = 'Name must be between 2 to 30 chars';
    }
    
    if(Validator.isEmpty(data.name)) {
        errors.name = 'Name field is required';
    }

    if(!Validator.isEmail(data.email)) {
        errors.email = 'Email is invalid';
    }

    if(Validator.isEmpty(data.email)) {
        errors.email = 'Email is required';
    }

    if(!Validator.isLength(data.password, {min: 6, max: 30})) {
        errors.password = 'Password must have 6 chars';
    }

    if(Validator.isEmpty(data.password)) {
        errors.password = 'Password is required';
    }

    if(!Validator.isLength(data.password_confirm, {min: 6, max: 30})) {
        errors.password_confirm = 'Password must have 6 chars';
    }

    if(!Validator.equals(data.password, data.password_confirm)) {
        errors.password_confirm = 'Password and Confirm Password must match';
    }

    if(Validator.isEmpty(data.password_confirm)) {
        errors.password_confirm = 'Password is required';
    }

    return {
        errors,
        isValid: isEmpty(errors)
    }
}

Here, I have used validator function to check the input values and based on the values, if the values are empty or not formatted correctly, or length is not defined in the rules then, it fills an error object and sends back to the client.

Here all the input values are checked to see the validation and if it fails then error object will be sent back to the user and display that errors in proper format.

Also same for login form validation. So inside validation folder, create one file called login.js and add the following code.

// login.js

const Validator = require('validator');
const isEmpty = require('./is-empty');

module.exports = function validateLoginInput(data) {
    let errors = {};
    data.email = !isEmpty(data.email) ? data.email : '';
    data.password = !isEmpty(data.password) ? data.password : '';

    if(!Validator.isEmail(data.email)) {
        errors.email = 'Email is invalid';
    }

    if(Validator.isEmpty(data.email)) {
        errors.email = 'Email is required';
    }

    if(!Validator.isLength(data.password, {min: 6, max: 30})) {
        errors.password = 'Password must have 6 chars';
    }

    if(Validator.isEmpty(data.password)) {
        errors.password = 'Password is required';
    }

    return {
        errors,
        isValid: isEmpty(errors)
    }
}

#6: Create routes for register and login.

We are using jwt-authentication, so we need to create a passport’s jwt strategy. So inside the backend folder, we need to create one file called passport.js. Write the following code inside passport.js.

// passport.js

const JWTStrategy = require('passport-jwt').Strategy;
const ExtractJWT = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const User = mongoose.model('users');
const opts = {};

opts.jwtFromRequest = ExtractJWT.fromAuthHeaderAsBearerToken();
opts.secretOrKey = 'secret';

module.exports = passport => {
    passport.use(new JWTStrategy(opts, (jwt_payload, done) => {
        User.findById(jwt_payload.id)
            .then(user => {
                if(user) {
                    return done(null, user);
                }
                return done(null, false);
            })
            .catch(err => console.error(err));
    }));
}

Inside the backend folder, create one folder called routes and inside that folder, create one file called user.js and add the following code inside it.

// user.js

const express = require('express');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const passport = require('passport');
const validateRegisterInput = require('../validation/register');
const validateLoginInput = require('../validation/login');

const User = require('../models/User');

router.post('/register', function(req, res) {

    const { errors, isValid } = validateRegisterInput(req.body);

    if(!isValid) {
        return res.status(400).json(errors);
    }
    User.findOne({
        email: req.body.email
    }).then(user => {
        if(user) {
            return res.status(400).json({
                email: 'Email already exists'
            });
        }
        else {
            const avatar = gravatar.url(req.body.email, {
                s: '200',
                r: 'pg',
                d: 'mm'
            });
            const newUser = new User({
                name: req.body.name,
                email: req.body.email,
                password: req.body.password,
                avatar
            });
            
            bcrypt.genSalt(10, (err, salt) => {
                if(err) console.error('There was an error', err);
                else {
                    bcrypt.hash(newUser.password, salt, (err, hash) => {
                        if(err) console.error('There was an error', err);
                        else {
                            newUser.password = hash;
                            newUser
                                .save()
                                .then(user => {
                                    res.json(user)
                                }); 
                        }
                    });
                }
            });
        }
    });
});

router.post('/login', (req, res) => {

    const { errors, isValid } = validateLoginInput(req.body);

    if(!isValid) {
        return res.status(400).json(errors);
    }

    const email = req.body.email;
    const password = req.body.password;

    User.findOne({email})
        .then(user => {
            if(!user) {
                errors.email = 'User not found'
                return res.status(404).json(errors);
            }
            bcrypt.compare(password, user.password)
                    .then(isMatch => {
                        if(isMatch) {
                            const payload = {
                                id: user.id,
                                name: user.name,
                                avatar: user.avatar
                            }
                            jwt.sign(payload, 'secret', {
                                expiresIn: 3600
                            }, (err, token) => {
                                if(err) console.error('There is some error in token', err);
                                else {
                                    res.json({
                                        success: true,
                                        token: `Bearer ${token}`
                                    });
                                }
                            });
                        }
                        else {
                            errors.password = 'Incorrect Password';
                            return res.status(400).json(errors);
                        }
                    });
        });
});

router.get('/me', passport.authenticate('jwt', { session: false }), (req, res) => {
    return res.json({
        id: req.user.id,
        name: req.user.name,
        email: req.user.email
    });
});

module.exports = router;

So, here, I have defined the two post routes.

  1. Register.
  2. Login.

Inside the post route of the register, we first check the validation for all of our inputs. If the errors exist, then there is no need for the further process. So sent back the error response to the client.

After that, we check, if the email already exists, if so we need to send an error response to the client.

Otherwise, we fetch the avatar based on email address, if an avatar is not there then by default will be sent back as a response.

Then we create a hash value of the password and save the user in the database successfully and send back that user to the client.

Now, for login the user, first, we check the validation same as a register.

Then go for checking the email, and if the email is not found, then we send back the error to the client saying that user is not found.

If email is proper, then we check password with bcrypt’s compare method. If the match is found, then we need to generate the jwt token.

We use the user object as a payload and give a secret key to generate JWT token and send back that token to the user and logged in the user.

Also, I have used get route, and that is /me.

If the user is logged in and it has the jwt token then and then it can access this route otherwise he will redirect back to log in because this route is protected.

Finally, import passport.js file and routes >> user.js file inside backend >> app.js file.

So, our final app.js file looks like below.

// app.js

const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const config = require('./db');

const users = require('./routes/user'); 

mongoose.connect(config.DB, { useNewUrlParser: true }).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database'+ err)}
);

const app = express();
app.use(passport.initialize());
require('./passport')(passport);

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use('/api/users', users);

app.get('/', function(req, res) {
    res.send('hello');
});

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => {
    console.log(`Server is running on PORT ${PORT}`);
});

So, we have completed our backend for this React Redux Node MongoDB JWT Authentication Tutorial. Now, we need to build a frontend using React.js and Redux.

#7: Create React.js project using create-react-app.

For generating the react.js project. We need to go to the root of the jwtauth folder and type the following command.

create-react-app frontend

 

React Redux Authentication

Now, go to the frontend folder.

cd frontend

Install the dependencies using the following command.

yarn add axios bootstrap classnames jwt-decode react-redux react-router-dom redux redux-thunk

# or

npm install --save axios bootstrap classnames jwt-decode react-redux react-router-dom redux redux-thunk

Now, inside package.json file of the frontend project, we need to add a proxy, so that we can avoid the CORS problem because of its a cross-origin request from frontend to backend. The react.js project will be running on PORT: 3000 and Node.js project will be on the PORT: 5000. So CORS problem will arise. To avoid that, we need to add a proxy. It simulates as one server in which react.js is running, but both are different.

So our final package.json file looks like below.

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.1.2",
    "classnames": "^2.2.6",
    "jwt-decode": "^2.2.0",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-redux": "^5.0.7",
    "react-router-dom": "^4.3.1",
    "react-scripts": "1.1.4",
    "redux": "^4.0.0",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:5000"
}

Here, we have added proxy server to node.js server. So that our api request will look like this.

http://localhost:3000/api/users/register

Although, our primary node server will be running on port:5000. If you try the API in postman, then you have to send a POST request to the following URL.

http://localhost:5000/api/users/register

But, we have added a proxy, so now we can send a post request from the 3000 port and also receive to the 3000 port. Thus, both domains are the same, and we do not face the CORS error.

Import the bootstrap inside src >> App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends Component {
  render() {
    return (
      <div>
        React Redux Auth App
      </div>
    );
  }
}

export default App;

Save the file and start the React development server using the following command.

npm start

#8: Create a Navbar.

Inside src folder, create one folder called components and inside that folder, create one file called Navbar.js and add the following code.

// Navbar.js

import React, { Component } from 'react';

class Navbar extends Component {
    render() {
        return(
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <a class="navbar-brand" href="#">Redux Auth</a>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav ml-auto">
                        <li class="nav-item">
                            <a class="nav-link" href="#">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Register</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#">Login</a>
                        </li>
                    </ul>
                </div>
            </nav>
        )
    }
}
export default Navbar;

Import this Navbar.js file inside the App.js file.

// App.js

import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Navbar from './components/Navbar';

class App extends Component {
  render() {
    return (
      <div>
        <Navbar />
      </div>
    );
  }
}

export default App;

#9: Create a Register component.

Inside src >> components folder, create one component called Register.js and add the following code.

// Register.js

import React, { Component } from 'react';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        console.log(user);
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className="form-control"
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className="form-control"
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

export default Register;

Okay, so when now fill all the textbox values and hit the Register button, you can see that, we got all the values inside out console of the browser.

Same we can create a Login component inside components folder. Add the following code inside Login.js file.

// Login.js

import React, { Component } from 'react';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        console.log(user);
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

export default Login;

#10: Setup the React Router.

We forget to create one component called Home. So let us create inside the components folder.

// Home.js

import React, { Component } from 'react';

export default class Home extends Component {
    render() {
        return (
            <div>
                Home Component
            </div>
        );
    }
}

Inside the src >> App.js file add the following code.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

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

class App extends Component {
  render() {
    return (
      <Router>
          <div>
            <Navbar />
              <Route exact path="/" component={ Home } />
              <div className="container">
                <Route exact path="/register" component={ Register } />
                <Route exact path="/login" component={ Login } />
              </div>
          </div>
        </Router>
    );
  }
}

export default App;

Also, we need to add the Link to the components >> Navbar.js file.

// Navbar.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';

class Navbar extends Component {
    render() {
        return(
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <Link className="navbar-brand" to="/">Redux Node Auth</Link>
                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul className="navbar-nav ml-auto">
                        <li className="nav-item">
                            <Link className="nav-link" to="/register">Sign Up</Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link" to="/login">Sign Up</Link>
                        </li>
                        <li className="nav-item">
                            <Link className="nav-link" to="/">Home</Link>
                        </li>
                    </ul>
                </div>
            </nav>
        )
    }
}
export default Navbar;

Now, we can navigate through different links using React Router.

#11: Setup a Redux Store.

Inside the src folder, create two folders.

  1. actions
  2. reducers

Inside reducers folder, create one file called index.js and add the following code in it.

// index.js

import { combineReducers } from 'redux';

export default combineReducers({
   
});

Right now, we do not have any reducers. But we will have reducer files in the future.

Inside the src folder, create one file called store.js and add the following code in it.

// store.js

import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const inititalState = {};

const store = createStore(
        rootReducer, 
        inititalState, 
        compose(applyMiddleware(thunk), 
                window.__REDUX_DEVTOOLS_EXTENSION__&& window.__REDUX_DEVTOOLS_EXTENSION__()));

export default store;

Here, we have used redux-thunk middleware to deal with AJAX or network request through redux.

Also, I have used the compose function. We have used a chrome extension to display our store data in that extension. So we have connected our Redux application to that extension.

Now we need to pass this store into our React application. So modify the src >> App.js file with the following code.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

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

class App extends Component {
  render() {
    return (
      <Provider store = { store }>
        <Router>
            <div>
              <Navbar />
                <Route exact path="/" component={ Home } />
                <div className="container">
                  <Route exact path="/register" component={ Register } />
                  <Route exact path="/login" component={ Login } />
                </div>
            </div>
          </Router>
        </Provider>
    );
  }
}

export default App;

#12: Create actions.

We create two actions throughout our project.

  1. GET_ERRORS
  2. SET_CURRENT_USER

So inside actions folder, create one file called types.js and add the following code in it.

// types.js

export const GET_ERRORS = 'GET_ERRORS';
export const SET_CURRENT_USER = 'SET_CURRENT_USER';

Also, inside actions folder, create one file called authentication.js and add the following code.

Write the following code inside an authentication.js file.

// authentication.js

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

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                console.log(res.data);
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

So, from this file, we will send an AJAX request to the node.js server. We can not write this code inside Reducer because otherwise, it is a violation of pure function. So we need to write any database operations from actions.

If we get any errors, then we dispatch the actions and reducer will handle that for us.

#13: Create reducers.

Inside reducers folder, create one file called errorReducer.js and add the following code.

// errorReducer.js

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

const initialState = {};

export default function(state = initialState, action ) {
    switch(action.type) {
        case GET_ERRORS:
            return action.payload;
        default: 
            return state;
    }
}

If any errors occur then this reducer fill the state with errors and we can display that errors from the frontend. Now, import this errorReducer.js file inside reducers >> index.js file.

// index.js

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

export default combineReducers({
    errors: errorReducer
});

#14: Create a validation.

Inside src folder, create one file called is-empty.js and add the following code in it.

// is-empty.js

const isEmpty = (value) => {
    return (
        value === undefined ||
        value === null ||
        (typeof value === 'object' && Object.keys(value).length === 0) ||
        (typeof value === 'string' && value.trim().length === 0)
    );
}
export default isEmpty;

We need this file when we check whether the user is authenticated or not.

#15: Connect Register component to Redux store.

Okay, so now it’s time to connect our Register.js file to the Redux store. For that, we use the connect method provided by react-redux.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className="form-control"
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className="form-control"
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

Now, register the user with the empty value and analyze the console. You can see that its 400 Bad Request because we are getting errors. We need to figure it somehow out how we can display the errors.

#16: Display the Validation errors.

We have already installed the module called classnames. We just need to render conditional errors. So we can write the Register.js file like below.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';
import classnames from 'classnames';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const { errors } = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.name
                    })}
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                    {errors.name && (<div className="invalid-feedback">{errors.name}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })}
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password_confirm
                    })}
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                    {errors.password_confirm && (<div className="invalid-feedback">{errors.password_confirm}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

We can see the errors like below image.

 

Redux Node Mongodb Authentication

If all of the values of the input box is right and valid then we can be able to sign up and redirect to login page.

#17: Connect Login component to Redux Store.

Edit the Login.js file with the following code.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentWillReceiveProps(nextProps) {

        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className="form-control"
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className="form-control"
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

Now, try to login the user with the empty values and analyze the console. You can see that its 400 Bad Request because we are getting errors. We use same classnames module to display the errors.

So edit the Login.js component with the following code.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';
import classnames from 'classnames';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentWillReceiveProps(nextProps) {

        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const {errors} = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })} 
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

Now, we can see the validation errors.

 

Redux JWT Authentication

Now, if all of your credentials are right then we will get a token in response and we can see that token inside our console right now.

After getting a token, we need to store that token inside localStorage and set the header to add that token in the future request. So when we try to access any protected route then due to jwt token, we can access that route very easily.

#18: Set the Auth token.

Inside src folder, create one file called setAuthToken.js and add the following code.

// setAuthToken.js

import axios from 'axios';

const setAuthToken = token => {
    if(token) {
        axios.defaults.headers.common['Authorization'] = token;
    }
    else {
        delete axios.defaults.headers.common['Authorization'];
    }
}

export default setAuthToken;

Okay, now we have set the headers and add the Authorization to a token. Now, we need to save this token and set the current user as a logged in user.

Write the following code inside actions >> authentication.js file.

// authentication.js

import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types';
import setAuthToken from '../setAuthToken';
import jwt_decode from 'jwt-decode';

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                const { token } = res.data;
                localStorage.setItem('jwtToken', token);
                setAuthToken(token);
                const decoded = jwt_decode(token);
                dispatch(setCurrentUser(decoded));
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const setCurrentUser = decoded => {
    return {
        type: SET_CURRENT_USER,
        payload: decoded
    }
}

Also, we need to create one more reducer called authReducer.js and add the following code inside it.

// authReducer.js

import { SET_CURRENT_USER } from '../actions/types';
import isEmpty from '../validation/is-empty';

const initialState = {
    isAuthenticated: false,
    user: {}
}

export default function(state = initialState, action ) {
    switch(action.type) {
        case SET_CURRENT_USER:
            return {
                ...state,
                isAuthenticated: !isEmpty(action.payload),
                user: action.payload
            }
        default: 
            return state;
    }
}

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

// index.js

import { combineReducers } from 'redux';
import errorReducer from './errorReducer';
import authReducer from './authReducer';

export default combineReducers({
    errors: errorReducer,
    auth: authReducer
});

#19: Create a Logout.

Now, we need to connect the redux store to the component >> Navbar.js file and also we need to change the Navbar based on the User is logged in or not.

So write the following code inside Navbar.js file.

// Navbar.js

import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { logoutUser } from '../actions/authentication';
import { withRouter } from 'react-router-dom';

class Navbar extends Component {

    onLogout(e) {
        e.preventDefault();
        this.props.logoutUser(this.props.history);
    }

    render() {
        const {isAuthenticated, user} = this.props.auth;
        const authLinks = (
            <ul className="navbar-nav ml-auto">
                <a href="#" className="nav-link" onClick={this.onLogout.bind(this)}>
                    <img src={user.avatar} alt={user.name} title={user.name}
                        className="rounded-circle"
                        style={{ width: '25px', marginRight: '5px'}} />
                            Logout
                </a>
            </ul>
        )
      const guestLinks = (
        <ul className="navbar-nav ml-auto">
            <li className="nav-item">
                <Link className="nav-link" to="/register">Sign Up</Link>
            </li>
            <li className="nav-item">
                <Link className="nav-link" to="/login">Sign In</Link>
            </li>
        </ul>
      )
        return(
            <nav className="navbar navbar-expand-lg navbar-light bg-light">
                <Link className="navbar-brand" to="/">Redux Node Auth</Link>
                <div className="collapse navbar-collapse" id="navbarSupportedContent">
                    {isAuthenticated ? authLinks : guestLinks}
                </div>
            </nav>
        )
    }
}
Navbar.propTypes = {
    logoutUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    auth: state.auth
})

export default connect(mapStateToProps, { logoutUser })(withRouter(Navbar));

Now, we need to create a logoutUser action inside actions >> authentication.js file.

// authentication.js

import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types';
import setAuthToken from '../setAuthToken';
import jwt_decode from 'jwt-decode';

export const registerUser = (user, history) => dispatch => {
    axios.post('/api/users/register', user)
            .then(res => history.push('/login'))
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const loginUser = (user) => dispatch => {
    axios.post('/api/users/login', user)
            .then(res => {
                const { token } = res.data;
                localStorage.setItem('jwtToken', token);
                setAuthToken(token);
                const decoded = jwt_decode(token);
                dispatch(setCurrentUser(decoded));
            })
            .catch(err => {
                dispatch({
                    type: GET_ERRORS,
                    payload: err.response.data
                });
            });
}

export const setCurrentUser = decoded => {
    return {
        type: SET_CURRENT_USER,
        payload: decoded
    }
}

export const logoutUser = (history) => dispatch => {
    localStorage.removeItem('jwtToken');
    setAuthToken(false);
    dispatch(setCurrentUser({}));
    history.push('/login');
}

Now, we can be able to log out the user successfully and we can also see that Navbar items are changing according to the user is logged in or not.

#20: Check the logged in user status.

If any point in time, the user is logged in then he can not able to see the login or register route. For that, we need to add some code inside Register.js and Login.js file.

Our final Register.js file looks like below. We have added a componentDidMount method. If the current user is logged in user and trying to register the new user, then it prevents it and redirects to a home route.

// Register.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { registerUser } from '../actions/authentication';
import classnames from 'classnames';

class Register extends Component {

    constructor() {
        super();
        this.state = {
            name: '',
            email: '',
            password: '',
            password_confirm: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            password_confirm: this.state.password_confirm
        }
        this.props.registerUser(user, this.props.history);
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.auth.isAuthenticated) {
            this.props.history.push('/')
        }
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    componentDidMount() {
        if(this.props.auth.isAuthenticated) {
            this.props.history.push('/');
        }
    }

    render() {
        const { errors } = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Registration</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="text"
                    placeholder="Name"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.name
                    })}
                    name="name"
                    onChange={ this.handleInputChange }
                    value={ this.state.name }
                    />
                    {errors.name && (<div className="invalid-feedback">{errors.name}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })}
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Confirm Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password_confirm
                    })}
                    name="password_confirm"
                    onChange={ this.handleInputChange }
                    value={ this.state.password_confirm }
                    />
                    {errors.password_confirm && (<div className="invalid-feedback">{errors.password_confirm}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Register User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Register.propTypes = {
    registerUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
    auth: state.auth,
    errors: state.errors
});

export default connect(mapStateToProps,{ registerUser })(withRouter(Register))

Also, we need to add some code inside src >> App.js file. The final App.js file looks like below.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';
import jwt_decode from 'jwt-decode';
import setAuthToken from './setAuthToken';
import { setCurrentUser, logoutUser } from './actions/authentication';

import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';

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

if(localStorage.jwtToken) {
  setAuthToken(localStorage.jwtToken);
  const decoded = jwt_decode(localStorage.jwtToken);
  store.dispatch(setCurrentUser(decoded));

  const currentTime = Date.now() / 1000;
  if(decoded.exp < currentTime) {
    store.dispatch(logoutUser());
    window.location.href = '/login'
  }
}

class App extends Component {
  render() {
    return (
      <Provider store = { store }>
        <Router>
            <div>
              <Navbar />
                <Route exact path="/" component={ Home } />
                <div className="container">
                  <Route exact path="/register" component={ Register } />
                  <Route exact path="/login" component={ Login } />
                </div>
            </div>
          </Router>
        </Provider>
    );
  }
}

export default App;

And also we need to add componentDidMount inside Login.js file.

// Login.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { loginUser } from '../actions/authentication';
import classnames from 'classnames';

class Login extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            errors: {}
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

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

    handleSubmit(e) {
        e.preventDefault();
        const user = {
            email: this.state.email,
            password: this.state.password,
        }
        this.props.loginUser(user);
    }

    componentDidMount() {
        if(this.props.auth.isAuthenticated) {
            this.props.history.push('/');
        }
    }

    componentWillReceiveProps(nextProps) {
        if(nextProps.auth.isAuthenticated) {
            this.props.history.push('/')
        }
        if(nextProps.errors) {
            this.setState({
                errors: nextProps.errors
            });
        }
    }

    render() {
        const {errors} = this.state;
        return(
        <div className="container" style={{ marginTop: '50px', width: '700px'}}>
            <h2 style={{marginBottom: '40px'}}>Login</h2>
            <form onSubmit={ this.handleSubmit }>
                <div className="form-group">
                    <input
                    type="email"
                    placeholder="Email"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.email
                    })}
                    name="email"
                    onChange={ this.handleInputChange }
                    value={ this.state.email }
                    />
                    {errors.email && (<div className="invalid-feedback">{errors.email}</div>)}
                </div>
                <div className="form-group">
                    <input
                    type="password"
                    placeholder="Password"
                    className={classnames('form-control form-control-lg', {
                        'is-invalid': errors.password
                    })} 
                    name="password"
                    onChange={ this.handleInputChange }
                    value={ this.state.password }
                    />
                    {errors.password && (<div className="invalid-feedback">{errors.password}</div>)}
                </div>
                <div className="form-group">
                    <button type="submit" className="btn btn-primary">
                        Login User
                    </button>
                </div>
            </form>
        </div>
        )
    }
}

Login.propTypes = {
    loginUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired,
    errors: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    auth: state.auth,
    errors: state.errors
})

export  default connect(mapStateToProps, { loginUser })(Login)

So, finally our React Redux Node MongoDB JWT Authentication Example Tutorial is over.

Register with a new User and it will redirect to a login page.

Login with your credentials and you can see the avatar is appearing inside the navbar and links are also changed.

Now, try to access the login or register route and you will be redirected to the root or home route.

Next, try to log out and you will be on the login page.

I have put the whole code on Github.

You can find more on Redux here.

Github Code

The post React Redux Node MongoDB JWT Authentication Example appeared first on AppDividend.

]]>
https://appdividend.com/2018/07/18/react-redux-node-mongodb-jwt-authentication/feed/ 21
React Axios Tutorial Example From Scratch https://appdividend.com/2018/05/30/react-axios-tutorial-example-from-scratch/ https://appdividend.com/2018/05/30/react-axios-tutorial-example-from-scratch/#comments Wed, 30 May 2018 13:40:05 +0000 http://localhost/wordpress/?p=930 React Axios GET POST Example

In this demo project, I will show you how to create React Axios Tutorial Example from scratch. For this example, I will use Node.js, Express.js, and MongoDB as a backend server, framework, and database. On the frontend, I will use React.js and Bootstrap. In every project,  we need to create a REST API at some stage. Axios is a lightweight […]

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

]]>
React Axios GET POST Example

In this demo project, I will show you how to create React Axios Tutorial Example from scratch. For this example, I will use Node.js, Express.js, and MongoDB as a backend server, framework, and database. On the frontend, I will use React.js and Bootstrap. In every project,  we need to create a REST API at some stage. Axios is a lightweight HTTP client based similar to a Fetch API.

Axios is promise-based async/await library for the readable asynchronous code. We can easily integrate with React.js, and it is effortless to use in any frontend 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)

React Axios Tutorial Example

We start this example by installing the React.js using create-react-app.

Step 1: Install React.js

Install create-react-app globally using the following command. You need to enter this command in admin mode.

npm install -g create-react-app
create-react-app reactaxios

React Axios Tutorial Example From Scratch

Step 2: Install Bootstrap 4.

Install Bootstrap 4 using the following command.

npm install bootstrap --save

Include bootstrap.min.css file inside App.js file.

// App.js

import React, { Component } from 'react';

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

class App extends Component {
  render() {
    return (
      <div class="container">
        React Axios Tutorial
      </div>
    );
  }
}

export default App;

Okay, now we have successfully integrated Bootstrap 4.

Step 3: Create React components.

Inside the src folder, create a new folder called components.

Okay, inside components folder, create two components.

  1. Create.js
  2. Index.js
// Create.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Create Component!!</p>
            </div>
        )
    }
}
// Index.js

import React, { Component } from 'react';

export default class Index extends Component {
    render() {
        return (
            <div>
                <p>Welcome to Index Component!!</p>
            </div>
        )
    }
}

Step 4: Create Routing of the components.

Install the following routing library.

npm install react-router-dom --save

Go to index.js file and Wrap the BrowserRouter object around App.js component.

// App.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

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

Now, define the routes for each component.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Create from './components/Create';
import Index from './components/Index';

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

class App extends Component {
  render() {
    return (
      <Router>
        <div className="container">
          <h2>Welcome to React Express Tutorial</h2>
          <ul>
            <li><Link to={'/create'}>Create</Link></li>
            <li><Link to={'/index'}>List</Link></li>
          </ul>
          <hr />
          <Switch>
              <Route exact path='/create' component={ Create } />
              <Route path='/index' component={ Index } />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Now, go to this URL: http://localhost:3000/create.

Axios React Example

 

Step 5: Create a Navigation bar.

Okay, now write the following code inside App.js file.

// App.js

import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Create from './components/Create';
import Index from './components/Index';

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

class App extends Component {
  render() { 
    return (
      <Router>
        <div className="container">
          <nav className="navbar navbar-expand-lg navbar-light bg-light">
            <a className="navbar-brand">React Express App</a>
            <div className="collapse navbar-collapse" id="navbarSupportedContent">
              <ul className="navbar-nav mr-auto">
                <li className="nav-item"><Link to={'/create'} className="nav-link">Create</Link></li>
                <li className="nav-item"><Link to={'/index'} className="nav-link">List</Link></li>
              </ul>
              <hr />
            </div>
          </nav> <br />
          <Switch>
              <Route exact path='/create' component={ Create } />
              <Route path='/index' component={ Index } />
          </Switch>
        </div>
      </Router>
    );
  }
}

export default App;

Step 6: Create a Bootstrap 4 Form.

Add the HTML Form code inside Create.js.

// Create.js

import React, { Component } from 'react';

export default class Create extends Component {
    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Add New Server</h3>
                <form>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Add Node server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

Step 7: Submit The Create.js Form.

So, now we have two fields.

  1. server name
  2. server port

So we need to create two functions that can track both the values and set the state according to it. Also, create the third function that will send the POST request to the node.js server.

Now, I need to create an event that tracks the state of both the input types.

Finally, when we click the submit button, then data is provided to the server.

// Create.js

import React, { Component } from 'react';

export default class Create extends Component {

    constructor(props) {
        super(props);
        this.onChangeHostName = this.onChangeHostName.bind(this);
        this.onChangePort = this.onChangePort.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            name: '',
            port: ''
        }
    }
    onChangeHostName(e) {
        this.setState({
            name: e.target.value
        });
    }
    onChangePort(e) {
        this.setState({
            port: e.target.value
        });
    }
    onSubmit(e) {
        e.preventDefault();
        console.log(`name is ${this.state.name} and port is ${this.state.port}`);
        this.setState({
            name: '',
            port: ''
        })
    }

    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Add New Server</h3>
                <form onSubmit={this.onSubmit}>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" className="form-control" value={this.state.name}  onChange={this.onChangeHostName}/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" className="form-control" value={this.state.port}  onChange={this.onChangePort}/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Add Node server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

Step 8: Create backend Node.js server.

First, start the mongodb database server using the following command.

mongod

In the root folder, create one file called server.js.

Now, install the following node.js dependencies.

npm install express nodemon body-parser cors mongoose --save

Also, we need to install nodemon as a development dependency.

npm install nodemon --save-dev

Okay, now write the following code inside a server.js file.

// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

Now, create a DB.js file inside root folder.

// DB.js

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

Now, import this DB.js file into the server.js file and connect a node.js application to the mongodb database.

// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const PORT = 4000;
const cors = require('cors');
const config = require('./DB');

mongoose.connect(config.DB).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database' +err)
});

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

Now open the terminal, and you can see that our database is connected with our Node Express application.

Step 9: Create a Mongoose schema.

Create one folder inside root called models and inside that create one file called ServerPort.js

// ServerPort.js

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

// Define collection and schema for ServerPort
const ServerPort = new Schema({
  name: {
    type: String
  },
  port: {
      type: Number
  }
},{
    collection: 'servers'
});

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

Step 10: Create Express Routes.

Create one folder called routes. Inside that routes folder, create one file called ServerPortRouter.js.

// ServerPortRouter.js

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

const ServerPort = require('../models/ServerPort');

ServerPortRouter.route('/add').post(function (req, res) {
  const serverport = new ServerPort(req.body);
  serverport.save()
    .then(serverport => {
        res.json('Server added successfully');
    })
    .catch(err => {
    res.status(400).send("unable to save to database");
    });
});

ServerPortRouter.route('/').get(function (req, res) {
    ServerPort.find(function (err, serverports){
    if(err){
      console.log(err);
    }
    else {
      res.json(serverports);
    }
  });
});

module.exports = ServerPortRouter;

Here, I have defined both GET and POST request routes.

I have used Mongoose ORM to save the data in MongoDB database.

The final step is to import the ServerPortRouter.js file inside the server.js file.  The server.js file looks like below.

// server.js

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

const PORT = 4000;
const cors = require('cors');
const config = require('./DB');
const ServerPortRouter = require('./routes/ServerPortRouter');

mongoose.connect(config.DB).then(
    () => {console.log('Database is connected') },
    err => { console.log('Can not connect to the database' +err)
});

app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());

app.use('/serverport', ServerPortRouter);

app.listen(PORT, function(){
  console.log('Server is running on Port: ',PORT);
});

Step 11: Install Axios Library.

Okay, we will install Axios via npm using the following command.

npm install axios --save

Now, send the post request along with the form data to the node and express server.

First, we need to import the axios library inside Create.js and use that library to send a POST request.

// Create.js

import React, { Component } from 'react';
import axios from 'axios';

export default class Create extends Component {

    constructor(props) {
        super(props);
        this.onChangeHostName = this.onChangeHostName.bind(this);
        this.onChangePort = this.onChangePort.bind(this);
        this.onSubmit = this.onSubmit.bind(this);

        this.state = {
            name: '',
            port: ''
        }
    }
    onChangeHostName(e) {
        this.setState({
            name: e.target.value
        });
    }
    onChangePort(e) {
        this.setState({
            port: e.target.value
        });
    }
    onSubmit(e) {
        e.preventDefault();
        const serverport = {
            name: this.state.name,
            port: this.state.port
        }
        axios.post('http://localhost:4000/serverport/add', serverport)
        .then(res => console.log(res.data));
        
        this.setState({
            name: '',
            port: ''
        });
    }

    render() {
        return (
            <div style={{marginTop: 50}}>
                <h3>Add New Server</h3>
                <form>
                    <div className="form-group">
                        <label>Add Host Name:  </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <label>Add Server Port: </label>
                        <input type="text" className="form-control"/>
                    </div>
                    <div className="form-group">
                        <input type="submit" value="Add Node server" className="btn btn-primary"/>
                    </div>
                </form>
            </div>
        )
    }
}

Now, enter the values and submit the form.  Open your browser console panel and see the response.

React js Axios POST example

 

We can that values are saved in the MongoDB database.

MERN Stack Example

 

Step 12: Send Axios GET request.

Write the following code inside Index.js file.

// Index.js

import React, { Component } from 'react';
import axios from 'axios';
import TableRow from './TableRow';

export default class Index extends Component {

  constructor(props) {
      super(props);
      this.state = {serverports: []};
    }
    componentDidMount(){
      axios.get('http://localhost:4200/serverport')
      .then(response => {
        this.setState({ serverports: response.data });
      })
      .catch(function (error) {
        console.log(error);
      })
    }
    tabRow(){
        return this.state.serverports.map(function(object, i){
            return <TableRow obj={object} key={i} />;
        });
    }

    render() {
      return (
        <div className="container">
            <table className="table table-striped">
              <thead>
                <tr>
                  <td>ID</td>
                  <td>Name</td>
                  <td>Port</td>
                </tr>
              </thead>
              <tbody>
                {this.tabRow()}
              </tbody>
            </table>
        </div>
      );
    }
  }

Okay, now write the stateless component, and that is TableRow.js component, which we need to create inside components folder.

// TableRow.js

import React, { Component } from 'react';

class TableRow extends Component {
  render() {
    return (
        <tr>
          <td>
            {this.props.obj._id}
          </td>
          <td>
            {this.props.obj.name}
          </td>
          <td>
            {this.props.obj.port}
          </td>
        </tr>
    );
  }
}

export default TableRow;

Okay, now go to the http://localhost:3000/index

We can see that we have successfully sent an Axios GET request from React.js component.

So, in this example, we have seen axios get and post request.

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

Github Code

Steps to use Github Code

  1. Start the MongoDB server using this command: mongod
  2. Clone The Repository. Go into the project folder.
  3. Install all the dependencies using this command: npm install
  4. Start the Node.js server using this command: nodemon server
  5. Start the react.js development server using this command: yarn start
  6. Go to this URL: http://localhost:3000/create

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

]]>
https://appdividend.com/2018/05/30/react-axios-tutorial-example-from-scratch/feed/ 6
GatsbyJS Tutorial For Beginners https://appdividend.com/2018/05/11/gatsbyjs-tutorial-for-beginners/ https://appdividend.com/2018/05/11/gatsbyjs-tutorial-for-beginners/#respond Fri, 11 May 2018 13:08:48 +0000 http://localhost/wordpress/?p=711 GatsbyJS example

GatsbyJS Tutorial For Beginners is the today’s leading topic. Gatsby.js is a static PWA (Progressive Web App) generator. Gatsby is Blazing-fast static site generator for React. You get code and data splitting out-of-the-box. Gatsby loads only the critical HTML, CSS, data, and JavaScript so your site loads as fast as possible. Gatsby.js builds the fastest possible website. Instead of waiting […]

The post GatsbyJS Tutorial For Beginners appeared first on AppDividend.

]]>
GatsbyJS example

GatsbyJS Tutorial For Beginners is the today’s leading topic. Gatsby.js is a static PWA (Progressive Web App) generator. Gatsby is Blazing-fast static site generator for React. You get code and data splitting out-of-the-box. Gatsby loads only the critical HTML, CSS, data, and JavaScript so your site loads as fast as possible. Gatsby.js builds the fastest possible website. Instead of waiting to generate pages when requested, pre-build pages and lift them into a global cloud of servers — ready to be delivered instantly to your users wherever they are. You can find more about GatsbyJS on their official website.

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.

GatsbyJS is SEO friendly Static Site Generator. So it is beneficial to create blogs.

GatsbyJS Tutorial For Beginners

As usual, we start our tutorial by installing it on our machine.

Step 1: Install GatsbyJS.

We need to install Gatsby CLI using the following command.

npm install -g gatsby-cli

If you find any error in installation, then run in administrator mode.

For creating a new website, type the following command.

gatsby new mjweb

 

GatsbyJS Tutorial For Beginners

Now, go into the website folder.

cd mjweb

Start a hot-reloading development environment by the following command.

gatsby develop

 

GatsbyJS - Static site generator for React

It is accessible at http://localhost:8000.

Gatsby React Site Generator

 

Open the folder in your favorite editor.

code .

Step 2: Gatsby Starters.

The Gatsby CLI tool lets you install “starters.” These are partially built sites preconfigured to help you get moving faster on creating a particular type of site.

For example, to quickly create a blog using Gatsby, you could install the Gatsby Starter Blog by running:

gatsby new blog https://github.com/gatsbyjs/gatsby-starter-blog

Go to that site and install all the dependencies.

npm install

If you don’t specify a custom starter, your site will be created from the default starter.

Several starters can be created.

You can find more about starter templates on this link.

Step 3: Start development server on HTTPs.

Our application can also start on HTTPs using the following command.

sudo gatsby develop --https

It can now run on localhost with HTTPs protocol.

Gatsby on HTTPs

 

Step 4: Building with Components.

React’s component architecture simplifies building large websites by encouraging modularity, reusability, and clear abstractions. React has a broad ecosystem of open source components, tutorials, and tooling that can be used seamlessly for building sites with Gatsby.

Let us create a new component inside src  >>  pages folder. The name of the file is app.js.

// app.js

import React from 'react'

const App = () => (
    <div>
        <h3>Hello from app component</h3>
    </div>
  )
  
export default App

It is a simple React.js component.

Now, if you create new components inside pages folder, then React routing will automatically define its URL path and its component. In our case, the file name is app.js, so the path becomes app and component is App. So it maps automatically and now browses the following URL: https://localhost:8000/app

You can see that the template is the parent component but child component is also rendering, and child component is our app.js file. 

So, if you need to create more and more pages, then you merely create inside pages folder.

Adding a 404 Page.

You can place a 404.js page inside pages directory. When you try to access the page that is not accessible, then it can show this page. There is already 404.js page is built inside pages directory.

Adding Images

You can import images as a Javascript module using webpack.

Let us take an image and copy our images inside pages directory.

Now, in our app.js file, we can import the image like this.

// app.js

import React from 'react'
import user from "./Krunal.jpg"; 

const App = () => (
    <div>
        <h3>Hello from app component</h3>
        <img src={user} />
    </div>
  )
  
  export default App

Now, you will be able to see the image. If you open that image in another tab then you can see that the image is hosted on public >>  static directory with a modified name. So behind the scenes, it renames and copy that image inside public  >> static directory.

Step 5: Production Build

You can build an optimized build using the following command.

gatsby build

Gatsby will perform an optimized production build for your site generating static HTML and per-route JavaScript code bundles.

Deployment

You can many options on Gatsby’s official website.

GatsbyJS Tutorial For Beginners is over. In upcoming tutorials. we will build a blog and deep dive into the GatsbyJS.

The post GatsbyJS Tutorial For Beginners appeared first on AppDividend.

]]>
https://appdividend.com/2018/05/11/gatsbyjs-tutorial-for-beginners/feed/ 0
Next js Tutorial For Beginners https://appdividend.com/2018/04/28/next-js-tutorial-for-beginners/ https://appdividend.com/2018/04/28/next-js-tutorial-for-beginners/#respond Sat, 28 Apr 2018 22:25:44 +0000 http://localhost/wordpress/?p=590 Next js Tutorial For Beginners

Next js Tutorial For Beginners is the today’s topic. It is no secret that creating single-page applications can be immensely challenging these days. But with the help of some libraries, frameworks, and tools, it is effortless nowadays. React.js is the common frontend libraries among the Front-end developers. Its virtual dom theory makes React faster and gives us […]

The post Next js Tutorial For Beginners appeared first on AppDividend.

]]>
Next js Tutorial For Beginners

Next js Tutorial For Beginners is the today’s topic. It is no secret that creating single-page applications can be immensely challenging these days. But with the help of some libraries, frameworks, and tools, it is effortless nowadays. React.js is the common frontend libraries among the Front-end developers. Its virtual dom theory makes React faster and gives us the better application performance. Now, one problem is that Single Page Applications are not at all SEO friendly because it is rendered on the Client side and not Server side. So when the Search Engine crawlers try to send a request, they cannot get our meta content or description and not even the main content. Search Engines do not care about how your app is architected or whatever ideology was used to adjust and fetch the right material. Their bots are not as smart as using your apps as a real user would. All they care about is that once they send their spiders to crawl and index your site, whatever the server provides on the first request is what gets indexed. In our case, all they get is our div tag with an id and bundled JS file, and we can not index our website correctly. So some how, we need a SSR to tackle this problem and in React js, Next.js is the perfect solution.

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.

Next js Tutorial

The solution to this problem is Next js. We need to create the Server Side Rendered apps or SSR apps. Next js is kind of Framework, which we can use to produce the pages on the server side and return that page. So search engine crawler can crawl the website and can index properly. Now let us deep dive into Next.js Tutorial.

Step 1: Install React and Next js.

Okay, first create your project directory.

mkdir next-tutorial

Go into that directory.

cd next-tutorial

Now, install the react and react-dom with the following command.

yarn add react react-dom

# or

npm install react react-dom --save

Step 2: Create pages folder and files.

Inside the root folder, create one folder called pages.

In that folder, create one file called index.js.

// index.js

export default () => (
  <div>
    <p>Hello World!</p>
  </div>
)

Now, inside the package.json file, add the scripts.

{
  "scripts": {
    "dev": "next"
  },
  "dependencies": {
    "next": "^5.1.0",
    "react": "^16.3.2",
    "react-dom": "^16.3.2"
  }
}

Go to the root and open your terminal and start the development server.

npm run dev

It will boot up the server at Port: 3000: http://localhost:3000

You can see that our index.js component is rendered. Now, if you see the source of the page, it has complete HTML markup. So that means, the page is provided by the server and then it sends to the client.

Now, create the second page of pages directory called home.js.

// home.js

export default () => (
    <div>
      <p>
        <a href="https://appdividend.com" target="_blank">Home</a>
      </p>
    </div>
)

Now, go to this URL: http://localhost:3000/home

Without creating any other routes, you still get that home.js page. So it all handled by Next.js.

So, if you need to create any page, you need to create inside pages folder, and you need to pass that page name after the root URL, and you can access that page. By default, if you have not created any page, but still you try to access that page, 404 page will be displayed.

Step 3: Client side Rendering different pages.

Server-side rendering is very convenient in your first-page load, but when it comes to navigating inside the website or client-side,  the client-side rendering is a critical point to speed up the page load and improve the overall user experience. Next.js provides us a Link component that you can use to build links. 

// index.js

import Link from 'next/link'

export default () => (
  <div>
    <p>Hello World!</p>
    <Link href="/home">
      <a>Home!</a>
    </Link>
  </div>
)

And your home.js file looks like this.

// home.js

export default () => (
    <div>
      <p>
        <a href="https://appdividend.com" target="_blank">Home</a>
      </p>
    </div>
)

Now, you can be able to Navigate the home page at client-side.

Step 4: Error Pages

We can also define our own custom error page by creating a _error.js page inside pages folder.

// _error.js

import React from 'react'

export default class Error extends React.Component {
  static getInitialProps ({ res, xhr }) {
    const statusCode = res ? res.statusCode : (xhr ? xhr.status : null)
    return { statusCode }
  }

  render () {
    return (
        <p>{
          this.props.statusCode
          ? `${this.props.statusCode} not found`
          : 'An error occurred on client'
        }</p>
      )
  }
}

Now, stop the server and restart it and type the whatever URL except that, which are not included. For example, I can not access /youndu page. http://localhost:3000/yondu.So let us try to access that page and we get an error, which is our custom _error page.

Finally, our Next.js tutorial is over. Thanks for taking.

The post Next js Tutorial For Beginners appeared first on AppDividend.

]]>
https://appdividend.com/2018/04/28/next-js-tutorial-for-beginners/feed/ 0
React Styled Components Example Tutorial https://appdividend.com/2018/04/19/react-styled-components-example-tutorial/ https://appdividend.com/2018/04/19/react-styled-components-example-tutorial/#respond Thu, 19 Apr 2018 20:31:42 +0000 http://localhost/wordpress/?p=518 styled component tutorial

React Styled Components Example Tutorial is the topic, we discuss today. The styled components remove the mapping between components and styles. This means that when you’re defining your styles, you’re creating a standard React component. It is the new way to attach the styles to the components. Styled-Components is a new CSS tool, designed by Max Stoiber and Glen Maddern, which helps […]

The post React Styled Components Example Tutorial appeared first on AppDividend.

]]>
styled component tutorial

React Styled Components Example Tutorial is the topic, we discuss today. The styled components remove the mapping between components and styles. This means that when you’re defining your styles, you’re creating a standard React component. It is the new way to attach the styles to the components. Styled-Components is a new CSS tool, designed by Max Stoiber and Glen Maddern, which helps you organize CSS in your React project. It also works well with React Native. The traditional styling of websites depends heavily on an external stylesheet with CSS. It has been challenged advent of React and component-based UI design. So the styled components will be the one possible solution.

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.

Advantages of using Styled Components

  1. Getting rid of the mapping between styles and components.
  2. Building small and reusable components.
  3. Reducing the risk of specificity clash.

React Styled Components Example

The styled-components utilizes tagged template literals to style your components. Okay, first we install the React js, and then we explore the React styled-components.

Step 1: Install React.

Type the following command.

npx create-react-app styledcom

Go to the project folder styledcom.

cd styledcom

Open the project in your IDE or Editor. If you are using VSCode, then you can hit this command.

code .

Step 2: Install the styled components library.

I am using Yarn as a package manager. So let us pull the package by the following command.

yarn add styled-components

or

npm install styled-components --save

Next step is to open the src  >>  App.js file and modify the file.

// App.js

import React, { Component } from 'react';
import styled from 'styled-components'

const Blog = styled.h1`
  text-align: center;
  color: skyBlue;
`;

class App extends Component {
  render() {
    return (
      <Blog>AppDividend</Blog>
    );
  }
}

export default App;

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

npm start

It will open the browser at this URL: http://localhost:3000/.

You can see that we did not create the component traditionally, but still, it has been created and assign the styles as well.

We can create this Blog component traditionally this way.

// App.js

import React, { Component } from 'react';
import styled from 'styled-components'

const Blog = (props) => {
  return <h1 
          style={{ textAlign: 'center',color: 'skyBlue' }}>
          {props.title}
        </h1>
}

class App extends Component {
  render() {
    return (
      <Blog title="AppDividend" />
    );
  }
}

export default App;

Now, save and see. We will get the same output. But the styled-components looks clear in code.

We are creating the component and assign the styles on the fly. It is so cool.

Style Third party components with styled-components.

If we are importing some third party components then also, we can style with styled-components. Sometimes, we have essential third-party components like Button or Card.  We can override that design as well.

Let us say, In above example, we need to style the App.js component. Then, we will do the following code.

// App.js

import React, { Component } from 'react';
import styled from 'styled-components'

const Blog = styled.h1`
  text-align: center;
  color: skyBlue;
`;

class App extends Component {
  render() {
    return (
      <div className={this.props.className}>
        <Blog>AppDividend</Blog>
      </div>
    );
  }
}

export default styled(App)`
  background-color: #232020;
  border-radius: 5px;
`;

Now, we can see the styles applied to an App.js component.

Global Styles in styled-components

In the web development, we sometimes need the Global styles that apply to our whole web application including all of the web pages. So let us do that.

In our example, we need to inject our global styles inside src  >>  index.js file.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { injectGlobal } from 'styled-components';
import registerServiceWorker from './registerServiceWorker';

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

injectGlobal`
  body {
    background-color: #eddb53;
    padding: 0;
    margin: 0;
    font-family: cursive;
  }
`

registerServiceWorker();

React Styled Components Example Tutorial

Adapting styles based on props

Based on the component properties, it will adjust its styles. It is the if-else condition for the CSS styles. Dynamic based on the Data.

// App.js

import React, { Component } from 'react';
import styled from 'styled-components'

const Blog = styled.h1`
  text-align: center;
  color: skyBlue;
`;

const Button = styled.button`
  background: ${props => props.primary ? 'green' : 'white'};
  color: ${props => props.primary ? 'white' : 'green'};
  font-size: 1.5em;
  padding: 0.25em 1em;
  border: 2px solid green;
  border-radius: 5px;
  margin: 10px 10px 10px 10px
`;

class App extends Component {
  render() {
    return (
      <div className={this.props.className}>
        <Blog>AppDividend</Blog>
        <Button primary="styled">Styled</Button>
        <Button>Plain</Button>
      </div>
    );
  }
}

export default styled(App)`
  background-color: #232020;
  border-radius: 5px;
`;

styled-components tutorial in react and react native

In above example, based on the primary props, we have created two different styled buttons.

You can find more on their original documentation.

That is it for the React Styled Components Example. Thanks for taking.

The post React Styled Components Example Tutorial appeared first on AppDividend.

]]>
https://appdividend.com/2018/04/19/react-styled-components-example-tutorial/feed/ 0