Everything you need to know about React’s Context API

Everything you need to know about React’s Context API

In this article, I will walk you through the basics of the new Context API and why to use it in your next React based project.

In this article, I will walk you through the basics of the new Context API and why to use it in your next React based project.

React is one such UI library which gets frequent upgradation in terms of new features and concepts within months. One such additional concept or feature in version 16.3 gives us Context API which is an upgraded version of old concept of context in React which allow components to share data outside the parent-child relationship.

Let’s dive in!

Why do you need Context API in React?

Before we dive into the reason why React upgraded to Context API, let’s first be familiar with some basic terminologies which are used to introduce data manipulation and updation in React.

In React, Data is updated and manipulated by using some terms which we called as props and state.

Props or properties can be understood as the data or information that is being passed to the child component from a parent component.

While state can be easily understood as the data which is being managed within the component itself.

So if each component manage it own state, how could you share data between nested components? Yes, it is true that we have props to pass the data but that only works in parent-child relationship case.

For an instance, let’s take an example of an app which is composed of different types of nested components:

As seen in Image above, Child2 is the children of Child which is also child of Parent. That makes Child2 as the grandchild of Parent.

Now, let’s play with some code to understand it in a more simplest manner:

class Parent extends React.Component {
 state = {
 value: ‘Some value’
 };
 
 render() {
 return(
 <Child value={this.state.value} />
 );
 }
}
 
const Child = (props) => (
 <Child2 value={props.value} />
);
 
const Child2 = (props) => (
 <div>{props.value}</div>
);

In the above example, we are sending value from parent component (Parent here) through its child component Child, which is then supposed to be used inside component Child2. Here, Child component doesn’t care about the value (prop), it’s only passing down the prop to be used within component Child2. Now, this example might seem simple to you and you will wonder what’s the problem with that.

Let’s imagine for a second, if we not only have a Child component but Grandchild1 and Grandchild2 or further more components between Parent and Child2. In such case, you would need to pass the props further down to each of these components of the tree. But, by the definition of props mentioned above, value can be passed only in between Parent and Child.

Such kind of problem which could be a havoc for React performance is known as Prop drilling. In simpler terms, it relates to the passing down of props from the upper level i.e Parent to lower level components such as Child, Grandchild etc. in the component tree, where components in between doesn’t care about these props.

Although, you have libraries such as Redux to mitigate this kind of complexity but it’s worthless to use Redux in this case as it will make your app’s logic more complex. Nevertheless, this is where the concept of Context API in React comes into play.

When should you use React’s new Context API?

Using Context is the best fit for the use case where your codebase consists of lot of components that depends on a single piece of data, but are nested deep within the component tree.

Following image will give you an idea as in how deep your upper level, middle level and lower level components can be nested within a component tree:

Things you need to be familiar with before using React’s new Context API

As mentioned above, React’s new Context API provides a way to pass and store data down a React component tree without writing it into every layer of the component hierarchy. It does so by leveraging on two types of components:

Provider — The Provider component is used in higher hierarchy of the tree. It accepts a prop called as Value. It acts as a root component in the hierarchical tree such that any child in the tree can access the values that are provided by the context provider.

render() {return (
<Provider value={this.state.contextValue}>
{this.props.children}
</Provider>
);
}

Consumer — As the name implies, consumer consumes the data which is being passed, irregardless of how deeply nested it is located in the component tree. That means, Consumer don’t have to be necessarily be the child of Provider. Instead, it can access data from anywhere down the component tree.

A consumer renders the data by using a render prop API.

render() {return (
<Consumer>
{contextValue => <Child arbitraryProp={contextValue} />}
</Consumer>
)
}

How to use Context in your React Application?

Now that you are pretty much familiar with what’s up to the new Context API, now is the time for you to understand how to use Context in an application.

In React, you have a predefined function to create a Context:

const Context = React.createContext();

React.createContext is used to initialise the Context and it’s passed the initial value. It returns an object with a Provider and a Consumer. Providers and consumers come in pairs, that is, for each provider, there is a corresponding consumer.

The examples explained above are pretty much simpler to understand. Though, you always will have to play with more complex data and find a way to store that data down in the component tree so that other components could use it.

Let’s now re-implement the above example with the context API:

const Context = React.createContext();
class Parent extends React.Component {
state = { x: 1 };
handleContextChange = x => this.setState({ x });
render() {
const contextValue = {
data: this.state,
handleChange: this.handleContextChange
};
return (
<Context.Provider value={contextValue}>
<Child/>
</Context.Provider>
);
}
}
const Child = props => <div><GrandChild/></div>;
const GrandChild = props => (
<Context.Consumer>
{({ handleChange, data }) => (
<div>
<button onClick={() => handleChange(2)}>Change</button>
<Child2 text={data.x} />
</div>
)}
</Context.Consumer>
);
const Child2 = props => <p>{props.text}</p>;

In the above code snippet, we have started by initialising a context. Then we have use it in the top hierarchy which belongs to the component Parent. The State of Parent component is the value of Context.Provider. Upon changing the state, the Context.Provider gets a new value. Parent component is also used as the storage of our storage of the state so that the context can pass it down the hierarchy.

In the component GrandChild, we have used the Context.Consumer which receives a function via its children render prop. Upn changing the value of Context.Provider, this function is invoked repeatedly and renders with the new value finally.

Here, component Child which is between Parent and GrandChild is not aware about the whole context arrangement. Same is with component Child 2 and button element as they also don’t know about the context. These components just receive the data and the changeHandler function passed via their props and can use them further as any other prop.

Final Words

React’s new Context API is definitely not an alternative to the state management libraries such as Redux or MobX. Neither, it relies on passing a context down the component down the component tree. Instead, it provides a provider-consumer component pairs to communicate between the nested components in the hierarchy.

The top level components provide the data and the lower level components consume it without having to pass the data down the component hierarchical tree level-by-level.

With this article, you are good to start with using the React’s Context API in your apps. If you further want more relevant information about the API, don’t forget to go through the official documentation.

React and APIs - Full Tutorial - Hacker News API Application

React and APIs - Full Tutorial - Hacker News API Application

Learn how to use APIs with React in this intermediate tutorial. We're going to be creating a small application in React that calls the Hacker News API. We'll be looking at React memo, Axios (to make API calls), styled components, and finally we will test our work using React Testing Library.

React and APIs - Full Tutorial - Hacker News API Application

Once we have done all this we will run our application through Lighthouse (a browser extension) that allows us to test for accessibility, performance and so much more. We will be making 500+ automated API calls in this application, and I want to show you how to use memo with React so that we can avoid making multiple network calls if we already have the data.

💻 Code: https://github.com/karlhadwen/newsreader

⭐️ Course Contents ⭐️
⌨️ (0:00:00) Introduction (what are we building?), tech stack talk
⌨️ (0:01:50) Using create-react-app as our base
⌨️ (0:03:30) Stripping out the files & content that we do not need
⌨️ (0:05:00) Refactoring to named exports
⌨️ (0:08:35) Modifying our .env file
⌨️ (0:09:15) Scaffolding our application
⌨️ (0:10:15) Looking at the Hacker News Api
⌨️ (0:11:50) Looking at all the news article Ids
⌨️ (0:12:58) Adding Axios using Yarn
⌨️ (0:13:00) Creating our hnApi.js service file
⌨️ (0:15:07) Adding the ability to get all story Ids from HN Api
⌨️ (0:17:14) Starting work on App.js
⌨️ (0:22:30) Adding useEffect to App.js to show all story Ids
⌨️ (0:30:00) Explaining how useEffect works
⌨️ (0:36:00) Creating our StoriesContainer.js container/component
⌨️ (0:37:50) Adding the ability to get stories from HN Api
⌨️ (0:39:50) Demonstrating the results that we receive from the HN Api
⌨️ (0:41:30) Creating our Story.js component file
⌨️ (0:43:15) Adding our Story component to the StoriesContainer component
⌨️ (0:44:10) Adding storyId as a prop to the Story.js component
⌨️ (0:46:40) Adding state to our Story.js component
⌨️ (0:47:10) Using useEffect to get a story in our Story.js component
⌨️ (0:47:40) Adding validation when getting stories
⌨️ (0:49:00) Dumping our stories onto the page
⌨️ (0:49:55) Building out the Story.js component with real data
⌨️ (0:53:20) Adding a selector for the story fields
⌨️ (0:56:00) Adding styled components
⌨️ (0:57:00) Building out our StoryStyles.js file using styled components
⌨️ (0:59:00) Adding a title to StoriesContainer.js
⌨️ (1:00:00) Adding a StoryWrapper to our Story.js component
⌨️ (1:01:50) More work on styling
⌨️ (1:02:30) Adding styling for StoryMeta
⌨️ (1:03:55) Adding styling for StoryMetaElements & styled component props
⌨️ (1:04:55) Adding our styled components to our Story.js component
⌨️ (1:11:30) Adding StoriesContainerStyles for more styling on the container
⌨️ (1:12:05) Looking at adding global styles (createGlobalStyle)
⌨️ (1:13:00) Adding our container styles to StoriesContainer.js
⌨️ (1:14:55) Brief look at the React profiler
⌨️ (1:16:00) Quick run through as to what we have built so far
⌨️ (1:18:10) Making our time display properly using mapTime.js
⌨️ (1:22:00) Adding InfiniteScroll to our application (custom hook)
⌨️ (1:22:40) Constants to be used by InfiniteScroll for per page items
⌨️ (1:39:05) Adding debounce functionality for scrolling
⌨️ (1:42:00) Adding a fixture folder with fixtures for tests
⌨️ (1:46:00) Testing! Lets test App.js
⌨️ (1:48:00) Adding react-testing-library to our application
⌨️ (1:59:00) Adding Jest coverage (good practise to do so)
⌨️ (2:02:00) Testing the StoriesContainer.js
⌨️ (2:03:40) Testing the Story.js component
⌨️ (2:10:00) Testing the HnApi.js file
⌨️ (2:22:18) Looking at our coverage and more testing!
⌨️ (2:22:53) Collecting coverage from the right places
⌨️ (2:25:43) Looking at React memo
⌨️ (2:27:33) Adding memo to Story.js to prevent additional Api calls
⌨️ (2:29:18) Overview of what we have achieved!
⌨️ (2:30:29) Running our application through Lighthouse!
⌨️ (2:33:00) Thanks for watching, I hope you learned a lot!

How to CRUD Operations using Reactjs and ASP.NET Web API

How to CRUD Operations using Reactjs and ASP.NET Web API

In this article, I'm going to perform CRUD operations using React.js, ASP.NET Web API and SQL Server. ReactJS is an open-source JavaScript library that is used for creating user interfaces. It is developed and maintained by Facebook.

Introduction

In this article, I'm going to perform CRUD operations using  React.js and ASP.NET Web API. Reactjs is an open-source JavaScript library that is used for creating user interfaces. It is developed and maintained by Facebook. Learn more about React here.

Prerequisites

  • We should have the basic knowledge of React.js and Web API.
  • Visual Studio and Visual Studio Code IDE should be installed on your system.
  • SQL Server Management Studio.

Technologies we will use:

  • ASP.NET Web API.
  • ReactJS
  • SQL Server.
  • React strap.
  • Bootstrap

You may also like: Angular vs React vs Vue: Which one will be popular in 2020.

Step 1: Create a Table in the Database

Open SQL Server Management Studio, create a database named "CrudDemo," and in this database, create a table. Give that table a name like "studentmaster."

USE [CrudDemo]  
GO  
CREATE TABLE [dbo].[studentmaster](  
    [Id] [int] IDENTITY(1,1) NOT NULL,  
    [Name] [varchar](50) NULL,  
    [RollNo] [varchar](50) NULL,  
    [Class] [varchar](50) NULL,  
    [Address] [varchar](50) NULL,  
 CONSTRAINT [PK_studentmaster] PRIMARY KEY CLUSTERED   
(  
    [Id] ASC  
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]  
) ON [PRIMARY]  

GO  
Create a New Web API Project

Step 2: Create a New Project.

_Creating a new project in VS Code_

Step 3: Change the Name to CrudUsingReact

_Changing project name to CrudUsingReact_

Step 4: Choose the Web API Template

_Selecting Web API template_

Step 5

Right-click the Models folder from Solution Explorer and go to Add >> New Item >> data.

_Adding data_

Step 6

Click on the "ADO.NET Entity Data Model" option and click "Add."

_Adding Entity Data Model_

Step 7

Select EF Designer from the database and click the "Next" button.

_Choosing EF Designer_

Step 8

Add the connection properties and select database name on the next page and click OK.

_Adding connection properties to db_

Step 9

Check the "Table" checkbox. The internal options will be selected by default. Now, click the "Finish" button.

_Finishing project setup_

Step 10

Right-click on Models folder and add two classes — Student and Response. Now, paste the following codes in these classes:

public class Student  
   {  
       public string Name { get; set; }  
       public string Rollno { get; set; }  
       public string Class { get; set; }  
       public string Address { get; set; }  
   }  
public class Response  
   {  
       public string Status { get; set; }  
       public string Message { get; set; }  
   }  

Step 11

Right-click on the Controllers folder and add a new controller. Name it "Student controller" and add the following namespace in the Student controller.

using CrudUsingReact.Models;  

Step 12

Now, add a method to insert and update data into the database.

[Route("AddotrUpdatestudent")]  
       [HttpPost]  
       public object AddotrUpdatestudent(Student st)  
       {  
           try  
           {  
               if (st.Id == 0)  
               {  
                   studentmaster sm = new studentmaster();  
                   sm.Name = st.Name;  
                   sm.RollNo = st.Rollno;  
                   sm.Address = st.Address;  
                   sm.Class = st.Class;  
                   DB.studentmasters.Add(sm);  
                   DB.SaveChanges();  
                   return new Response  
                   {  
                       Status = "Success",  
                       Message = "Data Successfully"  
                   };  
               }  
               else  
               {  
                   var obj = DB.studentmasters.Where(x => x.Id == st.Id).ToList().FirstOrDefault();  
                   if (obj.Id > 0)  
                   {  

                       obj.Name = st.Name;  
                       obj.RollNo = st.Rollno;  
                       obj.Address = st.Address;  
                       obj.Class = st.Class;  
                       DB.SaveChanges();  
                       return new Response  
                       {  
                           Status = "Updated",  
                           Message = "Updated Successfully"  
                       };  
                   }  
               }  
           }  
           catch (Exception ex)  
           {  
               Console.Write(ex.Message);  
           }  
           return new Response  
           {  
               Status = "Error",  
               Message = "Data not insert"  
           };  

       }  

Step 13

Add other methods to delete and fetch data respectively from the database.

[Route("Deletestudent")]  
      [HttpDelete]  
      public object Deletestudent(int id)  
      {  
          var obj = DB.studentmasters.Where(x => x.Id == id).ToList().FirstOrDefault();  
          DB.studentmasters.Remove(obj);  
          DB.SaveChanges();  
          return new Response  
          {  
              Status = "Delete",  
              Message = "Delete Successfuly"  
          };  
      }  

[HttpGet]  
      public object   Studentdetails()  
      {  

              var a = DB.studentmasters.ToList();  
              return a;  
      }  

Complete Student Controller Code

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net;  
using System.Net.Http;  
using System.Web.Http;  
using CrudUsingReact.Models;  

namespace CrudUsingReact.Controllers  
{  
    [RoutePrefix("Api/Student")]  
    public class studentController : ApiController  
    {  
        CrudDemoEntities DB = new CrudDemoEntities();  
        [Route("AddotrUpdatestudent")]  
        [HttpPost]  
        public object AddotrUpdatestudent(Student st)  
        {  
            try  
            {  
                if (st.Id == 0)  
                {  
                    studentmaster sm = new studentmaster();  
                    sm.Name = st.Name;  
                    sm.RollNo = st.RollNo;  
                    sm.Address = st.Address;  
                    sm.Class = st.Class;  
                    DB.studentmasters.Add(sm);  
                    DB.SaveChanges();  
                    return new Response  
                    {  
                        Status = "Success",  
                        Message = "Data Successfully"  
                    };  
                }  
                else  
                {  
                    var obj = DB.studentmasters.Where(x => x.Id == st.Id).ToList().FirstOrDefault();  
                    if (obj.Id > 0)  
                    {  

                        obj.Name = st.Name;  
                        obj.RollNo = st.RollNo;  
                        obj.Address = st.Address;  
                        obj.Class = st.Class;  
                        DB.SaveChanges();  
                        return new Response  
                        {  
                            Status = "Updated",  
                            Message = "Updated Successfully"  
                        };  
                    }  
                }  
            }  
            catch (Exception ex)  
            {  
                Console.Write(ex.Message);  
            }  
            return new Response  
            {  
                Status = "Error",  
                Message = "Data not insert"  
            };  

        }  
        [Route("Studentdetails")]  
        [HttpGet]  
        public object   Studentdetails()  
        {  

                var a = DB.studentmasters.ToList();  
                return a;  
        }  

        [Route("StudentdetailById")]  
        [HttpGet]  
        public object StudentdetailById(int id)  
        {  
            var obj = DB.studentmasters.Where(x => x.Id == id).ToList().FirstOrDefault();  
            return obj;  
        }  
        [Route("Deletestudent")]  
        [HttpDelete]  
        public object Deletestudent(int id)  
        {  
            var obj = DB.studentmasters.Where(x => x.Id == id).ToList().FirstOrDefault();  
            DB.studentmasters.Remove(obj);  
            DB.SaveChanges();  
            return new Response  
            {  
                Status = "Delete",  
                Message = "Delete Successfuly"  
            };  
        }  
    }  
}  

Step 14

Now, let's enable CORS. Go to Tools, open NuGet Package Manager, search for CORS, and install the "Microsoft.Asp.Net.WebApi.Cors" package. Open Webapiconfig.cs and add the following lines:

EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*");    
config.EnableCors(cors);   
Create React.js Project

Step 15

To create a new ReactJS project, open the command prompt, and enter the following command:

npx create-react-app crudwithceactjs  

Open the newly created project in Visual Studio Code and install Reactstrap and Bootstrap by using the following commands:

npm install --save bootstrap  
npm install --save reactstrap react react-dom  

Step 16

Now, go to the "src" folder and add a new folder "Student" and four new components:

  1. Addstudent.js
  2. Studentlist.js
  3. Editstudent.js
  4. Table.js

_Adding components to the Student folder_

Step 17

Install the Axios library by using the following command. Learn more about Axios library

npm install --save axios  

Step 18

Add routing: Use the following command to add routing in React.

npm install react-router-dom --save    

Step 19

Now, open the Addstudent.js file and add the following code:

import React from 'react';  
import axios from 'axios';  
import '../Student/Addstudent.css'  
import { Container, Col, Form, Row, FormGroup, Label, Input, Button } from 'reactstrap';  
class Addstudent extends React.Component{  
constructor(props){  
super(props)  
this.state = {  
Name:'',  
RollNo:'',  
Class:'',  
Address:''  
}  
}   
Addstudent=()=>{  
  axios.post('http://localhost:52564/Api/Student/AddotrUpdatestudent/', {Name:this.state.Name,RollNo:this.state.RollNo,  
  Class:this.state.Class, Address:this.state.Address})  
.then(json => {  
if(json.data.Status==='Success'){  
  console.log(json.data.Status);  
  alert("Data Save Successfully");  
this.props.history.push('/Studentlist')  
}  
else{  
alert('Data not Saved');  
debugger;  
this.props.history.push('/Studentlist')  
}  
})  
}  

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

render() {  
return (  
   <Container className="App">  
    <h4 className="PageHeading">Enter Student Informations</h4>  
    <Form className="form">  
      <Col>  
        <FormGroup row>  
          <Label for="name" sm={2}>Name</Label>  
          <Col sm={10}>  
            <Input type="text" name="Name" onChange={this.handleChange} value={this.state.Name} placeholder="Enter Name" />  
          </Col>  
        </FormGroup>  
        <FormGroup row>  
          <Label for="address" sm={2}>RollNo</Label>  
          <Col sm={10}>  
            <Input type="text" name="RollNo" onChange={this.handleChange} value={this.state.RollNo} placeholder="Enter RollNo" />  
          </Col>  
        </FormGroup>  
        <FormGroup row>  
          <Label for="Password" sm={2}>Class</Label>  
          <Col sm={10}>  
            <Input type="text" name="Class" onChange={this.handleChange} value={this.state.Class} placeholder="Enter Class" />  
          </Col>  
        </FormGroup>  
        <FormGroup row>  
          <Label for="Password" sm={2}>Address</Label>  
          <Col sm={10}>  
            <Input type="text" name="Address" onChange={this.handleChange} value={this.state.Address} placeholder="Enter Address" />  
          </Col>  
        </FormGroup>  
      </Col>  
      <Col>  
        <FormGroup row>  
          <Col sm={5}>  
          </Col>  
          <Col sm={1}>  
          <button type="button" onClick={this.Addstudent} className="btn btn-success">Submit</button>  
          </Col>  
          <Col sm={1}>  
            <Button color="danger">Cancel</Button>{' '}  
          </Col>  
          <Col sm={5}>  
          </Col>  
        </FormGroup>  
      </Col>  
    </Form>  
  </Container>  
);  
}  

}  

export default Addstudent;  

Add a new file  Addstudet.css file and add the following CSS classes. Import this file in the  Addstudent.js component.

.PageHeading    
{    
  margin-top: 10px;    
  margin-bottom: 10px;    
  color :black !important;    
}    

Step 20

Now, add a Table.js file and add the following code:

import React, { Component } from 'react';  
import axios from 'axios';  
import { Link } from 'react-router-dom';  
class Table extends Component {  
  constructor(props) {  
    super(props);  
    }  

    DeleteStudent= () =>{  
     axios.delete('http://localhost:52564/Api/Student/Deletestudent?id='+this.props.obj.Id)  
    .then(json => {  
    if(json.data.Status==='Delete'){  
    alert('Record deleted successfully!!');  
    }  
    })  
    }  
  render() {  
    return (  
        <tr>  
          <td>  
            {this.props.obj.Name}  
          </td>  
          <td>  
            {this.props.obj.RollNo}  
          </td>  
          <td>  
            {this.props.obj.Class}  
          </td>  
          <td>  
            {this.props.obj.Address}  
          </td>  
          <td>  
          <Link to={"/edit/"+this.props.obj.Id} className="btn btn-success">Edit</Link>  
          </td>  
          <td>  
            <button type="button" onClick={this.DeleteStudent} className="btn btn-danger">Delete</button>  
          </td>  
        </tr>  
    );  
  }  
}  

export default Table;  

Step 21

Now, add a studentlist.js file and add the following code.

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

export default class Studentlist extends Component {  

  constructor(props) {  
      super(props);  
      this.state = {business: []};  
    }  
    componentDidMount(){  
      debugger;  
      axios.get('http://localhost:52564/Api/Student/Studentdetails')  
        .then(response => {  
          this.setState({ business: response.data });  
          debugger;  

        })  
        .catch(function (error) {  
          console.log(error);  
        })  
    }  

    tabRow(){  
      return this.state.business.map(function(object, i){  
          return <Table obj={object} key={i} />;  
      });  
    }  

    render() {  
      return (  
        <div>  
          <h4 align="center">Student List</h4>  
          <table className="table table-striped" style={{ marginTop: 10 }}>  
            <thead>  
              <tr>  
                <th>Name</th>  
                <th>RollNo</th>  
                <th>Class</th>  
                <th>Address</th>  
                <th colSpan="4">Action</th>  
              </tr>  
            </thead>  
            <tbody>  
             { this.tabRow() }   
            </tbody>  
          </table>  
        </div>  
      );  
    }  
  }  

Step 22

Add EditStudent.js file with the following code:

import React from 'react';   
import { Container, Col, Form, Row, FormGroup, Label, Input, Button } from 'reactstrap';  
import axios from 'axios'  
import '../Student/Addstudent.css'  
class Edit extends React.Component {  
    constructor(props) {  
        super(props)  

    this.onChangeName = this.onChangeName.bind(this);  
    this.onChangeRollNo = this.onChangeRollNo.bind(this);  
    this.onChangeClass = this.onChangeClass.bind(this);  
    this.onChangeAddress = this.onChangeAddress.bind(this);  
    this.onSubmit = this.onSubmit.bind(this);  

         this.state = {  
            Name: '',  
            RollNo: '',  
            Class: '',  
            Address: ''  

        }  
    }  

  componentDidMount() {  
      axios.get('http://localhost:52564/Api/Student/StudentdetailById?id='+this.props.match.params.id)  
          .then(response => {  
              this.setState({   
                Name: response.data.Name,   
                RollNo: response.data.RollNo,  
                Class: response.data.Class,  
                Address: response.data.Address });  

          })  
          .catch(function (error) {  
              console.log(error);  
          })  
    }  

  onChangeName(e) {  
    this.setState({  
        Name: e.target.value  
    });  
  }  
  onChangeRollNo(e) {  
    this.setState({  
        RollNo: e.target.value  
    });    
  }  
  onChangeClass(e) {  
    this.setState({  
        Class: e.target.value  
    });  
}  
    onChangeAddress(e) {  
        this.setState({  
            Address: e.target.value  
        });  
  }  

  onSubmit(e) {  
    debugger;  
    e.preventDefault();  
    const obj = {  
        Id:this.props.match.params.id,  
      Name: this.state.Name,  
      RollNo: this.state.RollNo,  
      Class: this.state.Class,  
      Address: this.state.Address  

    };  
    axios.post('http://localhost:52564/Api/Student/AddotrUpdatestudent/', obj)  
        .then(res => console.log(res.data));  
        debugger;  
        this.props.history.push('/Studentlist')  
  }  
    render() {  
        return (  
            <Container className="App">  

             <h4 className="PageHeading">Update Student Informations</h4>  
                <Form className="form" onSubmit={this.onSubmit}>  
                    <Col>  
                        <FormGroup row>  
                            <Label for="name" sm={2}>Name</Label>  
                            <Col sm={10}>  
                                <Input type="text" name="Name" value={this.state.Name} onChange={this.onChangeName}  
                                placeholder="Enter Name" />  
                            </Col>  
                        </FormGroup>  
                        <FormGroup row>  
                            <Label for="Password" sm={2}>RollNo</Label>  
                            <Col sm={10}>  
                                <Input type="text" name="RollNo" value={this.state.RollNo} onChange={this.onChangeRollNo} placeholder="Enter RollNo" />  
                            </Col>  
                        </FormGroup>  
                         <FormGroup row>  
                            <Label for="Password" sm={2}>Class</Label>  
                            <Col sm={10}>  
                                <Input type="text" name="Class" value={this.state.Class} onChange={this.onChangeClass} placeholder="Enter Class" />  
                            </Col>  
                        </FormGroup>  
                         <FormGroup row>  
                            <Label for="Password" sm={2}>Address</Label>  
                            <Col sm={10}>  
                                <Input type="text" name="Address"value={this.state.Address} onChange={this.onChangeAddress} placeholder="Enter Address" />  
                            </Col>  
                        </FormGroup>   
                    </Col>  
                    <Col>  
                        <FormGroup row>  
                            <Col sm={5}>  
                            </Col>  
                            <Col sm={1}>  
                          <Button type="submit" color="success">Submit</Button>{' '}  
                            </Col>  
                            <Col sm={1}>  
                                <Button color="danger">Cancel</Button>{' '}  
                            </Col>  
                            <Col sm={5}>  
                            </Col>  
                        </FormGroup>  
                    </Col>  
                </Form>  
            </Container>  
        );  
    }  

}  

export default Edit;  

Step 23

Open the App.js file with the following code in it.

import React from 'react';  
import Addstudent from './Student/Addstudent';  
import Studentlist from './Student/Studentlist';  
import EditStudent from './Student/EditStudent';  
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';  
import './App.css';  
function App() {  
  return (  
    <Router>  
      <div className="container">  
        <nav className="navbar navbar-expand-lg navheader">  
          <div className="collapse navbar-collapse" >  
            <ul className="navbar-nav mr-auto">  
              <li className="nav-item">  
                <Link to={'/Addstudent'} className="nav-link">Addstudent</Link>  
              </li>  
              <li className="nav-item">  
                <Link to={'/Studentlist'} className="nav-link">Student List</Link>  
              </li>  
            </ul>  
          </div>  
        </nav> <br />  
        <Switch>  
          <Route exact path='/Addstudent' component={Addstudent} />  
          <Route path='/edit/:id' component={EditStudent} />  
          <Route path='/Studentlist' component={Studentlist} />  
        </Switch>  
      </div>  
    </Router>  
  );  
}  

export default App;  

Add the following CSS classes in the App.css file.

.App {    
  text-align: center;    
}    
.navheader{    
  margin-top: 10px;    
  color :black !important;    
  background-color: #b3beca!important    
}    

Now, run the application by using the  npm start command and check the result.

Click on the Add Student button to add a new record into the database.

Click on the Edit button to update a record.

Click on the Delete button to delete a record.

Summary

In this article, we learned how to perform CRUD operations using React, Asp.net Web API, and SQL Server.

Thank for reading. Please share if you liked it!

Build Your First App with React's Context API

Build Your First App with React's Context API

Build Your First App with React's Context API. One of React's latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router.

Build Your First App with React's Context API. One of React's latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router.

One of React’s latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router. There are plenty of ways to avoid using Context, but sometimes it can be really useful.

One really good use case for Context is keeping track of authentication. In fact, React’s official documentation for the Context API mentions it can be used for authentication.

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.### Table of Contents

The examples in their documentation are helpful, but they don’t actually include an example of sharing the authenticated user. I’ll show you here how one way to use the new Context API to simply keep track of whether a user is authenticated, and some basic profile information.

React Context in a Nutshell

Before going too far down the rabbit hole, let me give you a quick introduction into the Context API. As of React version 16, React ships with a function called createContext that takes a single value parameter. Calling createContext gives you both a Provider and Consumer component.

You can render the Provider component anywhere in your app - in multiple places if you like. If there is a Consumer anywhere inside the Provider (even deeply nested somewhere), it will have access to that value parameter in the form of a render function as a child. Each Provider can also override the value. For example:

import { createContext } from 'react';

const { Provider, Consumer } = createContext('default value');

export default () =>
  <main>
    <Provider>
      <Consumer>{value => <span>{value}</span>}</Consumer>
    </Provider>
    <Provider value="overridden value">
      <div>
        <Consumer>{value => <span>{value}</span>}</Consumer>
      </div>
    </Provider>
  </main>
);

Will render the following:

<main>
  <span>default value</span>
  </div>
    <span>overridden value</span>
  </div>
</main>

Because Provider is just a component, you can easily create a wrapper component that passes its state into the value prop of the Provider. Then you will have access to that component’s state anywhere in the app via the Consumer. In this tutorial, I’ll show you how to use one component to keep track of auth state changes and pass that information down via the Context API.

Build a Simple React App

The quickest way to get started with React in my experience is using the official Create React App CLI. It bootstraps an app for you giving you some decent defaults. To use it, install it globally with NPM, then run it with the name of your app as a parameter. This will create a new folder with everything you need to get started, and will even install the dependencies for you. You can then run the app using yarn start.

npm install --global [email protected] [email protected]
create-react-app react-context
cd react-context
yarn start

You should now be able to see your app running by visiting [http://localhost:3000](http://localhost:3000 "http://localhost:3000") with your browser.

For this tutorial, I’ll show you how you can take advantage of the new Context API to cut down some of the boilerplate that is often paired with authentication. Before getting started with Context, you’ll need to set up authentication in order to tie it in.

Create an Okta Application

One simple way to add authentication to your project is with Okta. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:

If you don’t already have one, sign up for a forever-free developer account. Log in to your developer console, navigate to Applications, then click Add Application. Select Single-Page App, then click Next.

Since Create React App runs on port 3000 by default, you should add that as a Base URI and Login Redirect URI. Your settings should look like the following:

Click Done to save your app, then copy your Client ID and paste it as a variable into a file called .env.local in the root of your project. This will allow you to access the file in your code without needing to store credentials in source control. You’ll also need to add your organization URL (without the -admin suffix). Environment variables (other than NODE_ENV) need to start with REACT_APP_ in order for Create React App to read them, so the file should end up looking like this:

.env.local

REACT_APP_OKTA_CLIENT_ID={yourClientId}
REACT_APP_OKTA_ORG_URL=https://{yourOktaDomain}

The easiest way to add authentication with Okta is to use Okta’s React SDK. You’ll also need to add routes, which can be done using React Router. I’ll also have you start adding icons to the app (for now as an avatar icon to show you’re logged in).

yarn add @okta/[email protected] [email protected]

For routes to work properly using React Router, you need to wrap your whole application in a router (for the web, you need to use BrowserRouter). Similarly, to allow access to authentication anywhere in the app, you need to wrap the app in a Security component provided by Okta. Okta also needs access to the router, so the Security component should be nested inside the router. You should modify your src/index.js file to look like the following:

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Security } from '@okta/okta-react';

import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

const oktaConfig = {
  issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
  redirect_uri: `${window.location.origin}/implicit/callback`,
  client_id: process.env.REACT_APP_OKTA_CLIENT_ID,
};

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

registerServiceWorker();

Now in src/App.js you can use Routes that tell the app to only render a certain component if the current URL matches the given path. You can also use Links to create a link to that route (or page) and properly modify the browser’s history to work in a single-page app.

Go ahead and create a nav tag with links to the Home page (/) and a Profile page (/profile). Also, create a main tag containing your routes. For now just stub in some inline components that render the name of the page.

By using Okta’s SecureRoute you will find that whenever you try to go to that page you will need to be logged in. If you’re not currently logged in, you’ll be redirected to /implicit/callback to log in. In order for that route to actually log you in, you also need to create a route that renders Okta’s ImplicitCallback component.

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -1,4 +1,7 @@
 import React, { Component } from 'react';
+import { Link, Route } from 'react-router-dom';
+import { SecureRoute, ImplicitCallback } from '@okta/okta-react';
+
 import logo from './logo.svg';
 import './App.css';

@@ -9,10 +12,16 @@ class App extends Component {
         <header className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
           <h1 className="App-title">Welcome to React</h1>
+          <nav className="App-nav">
+            <Link to="/">Home</Link>
+            <Link to="/profile">Profile</Link>
+          </nav>
         </header>
-        <p className="App-intro">
-          To get started, edit <code>src/App.js</code> and save to reload.
-        </p>
+        <main className="App-intro">
+          <Route exact path="/" component={() => 'Home Page'} />
+          <SecureRoute exact path="/profile" component={() => 'Profile page'} />
+          <Route path="/implicit/callback" component={ImplicitCallback} />
+        </main>
       </div>
     );
   }

Note: You can apply a diff in git by copying it to a file and using the git apply command. If you’re following along this avoids having to write the file out manually. For example, if you save the above as a file named app.diff, then from your project folder, you could type git apply app.diff and it should apply those changes.

To make this look a little nicer, add a bit of CSS to let the header expand to the content, give the main part of the app some padding, and make the nav links a bit more readable.

src/App.css

--- a/src/App.css
+++ b/src/App.css
@@ -9,17 +9,35 @@

 .App-header {
   background-color: #222;
-  height: 150px;
+  min-height: 150px;
   padding: 20px;
   color: white;
 }

+.App-nav {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.App-nav a {
+  color: white;
+  padding: 0 5px;
+  text-decoration: none;
+  cursor: pointer;
+}
+
+.App-nav a:hover {
+  text-decoration: underline;
+}
+
 .App-title {
   font-size: 1.5em;
 }

 .App-intro {
   font-size: large;
+  margin: 1em;
 }

You should now have a slightly modified version of the default page from Create React App that says “Home page”. You should also now be able to click on the Profile link and you will be prompted to log in to your account. Upon success, you’ll be taken to the profile page, that at the moment just says Profile page.

Note: You may need to restart the development server after adding the environment variables. You can do this by going to the terminal running the server and hitting ctrl-c, then re-running the yarn start command.

Add a User Greeting with React Context

Using React’s new Context API, you can create a component that you will use to wrap your entire application, similar to the way BrowserRouter or Security works. Once that Provider is in place, you can access pieces of authentication anywhere in the application without a lot of boilerplate.

In this case, create a context using createContext. You’ll then check when the component is first mounted, and again whenever it updates, if the user is authenticated. If this is different from the current state, then it also checks for the user and saves that as well. The reason the state is only updated whenever the authentication is different from the previous state is that otherwise, the componentDidUpdate function would trigger another update, sending this component into an infinite render loop.

To keep this simple to use, the default export is the Context’s Consumer. The Provider component is exported separately and is wrapped with Okta’s withAuth to give it access to the auth prop.

Note: Checking authentication during componentDidUpdate is admittedly not the most efficient method. At the time of this writing, there is not a simple way to detect when the state of authorization changes, so this is a simple approach for demo purposes. This example might not work well for larger applications.

src/Auth.js

import React, { createContext, Component } from 'react';
import { withAuth } from '@okta/okta-react';

const AuthContext = createContext({
  user: null,
  isAuthenticated: null,
});

export default AuthContext.Consumer;

class AuthController extends Component {
  state = {
    user: null,
    isAuthenticated: null,
  }

  componentDidUpdate() {
    this.checkAuthentication();
  }

  componentDidMount() {
    this.checkAuthentication();
  }

  async checkAuthentication() {
    const isAuthenticated = await this.props.auth.isAuthenticated();
    if (isAuthenticated !== this.state.isAuthenticated) {
      const user = await this.props.auth.getUser();
      this.setState({ isAuthenticated, user });
    }
  }

  render() {
    return (
      <AuthContext.Provider value={this.state}>
        {this.props.children}
      </AuthContext.Provider>
    );
  }
}

export const AuthProvider = withAuth(AuthController);

The app’s main entry point now needs to be wrapped in the AuthProvider. It needs to be inside Security so that it can access the auth using withAuth.

src/index.js

--- a/src/index.js
+++ b/src/index.js
@@ -6,6 +6,7 @@ import { Security } from '@okta/okta-react';
 import './index.css';
 import App from './App';
 import registerServiceWorker from './registerServiceWorker';
+import { AuthProvider } from './Auth';

 const oktaConfig = {
   issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
@@ -16,7 +17,9 @@ const oktaConfig = {
 ReactDOM.render(
   <BrowserRouter>
     <Security {...oktaConfig}>
-      <App />
+      <AuthProvider>
+        <App />
+      </AuthProvider>
     </Security>
   </BrowserRouter>,
   document.getElementById('root')

Now that the Context Provider is set up and ready to go, you can start using the Consumer. For a quick example, try changing the homepage to greet the user when they’re logged in. If they aren’t logged in, keep the old message of Welcome to React.

React Contexts take a render function as its child element. The parameters passed in are going to be the state of the provider (the data passed into value). Because of this, to access the user, you need to pass in a function that expects an object containing the key user. If this is null then authentication is still loading. If it’s undefined then the user is not authenticated. Otherwise, it will contain the user’s basic profile information. Go ahead and ignore the loading state for now, and only greet the user once you have their information.

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -5,13 +5,21 @@ import { SecureRoute, ImplicitCallback } from '@okta/okta-react';
 import logo from './logo.svg';
 import './App.css';

+import Auth from './Auth';
+
+const welcomeUser = ({ user }) => user
+  ? `Welcome, ${user.given_name || user.name}!`
+  : 'Welcome to React';
+
 class App extends Component {
   render() {
     return (
       <div className="App">
         <header className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
-          <h1 className="App-title">Welcome to React</h1>
+          <h1 className="App-title">
+            <Auth>{welcomeUser}</Auth>
+          </h1>
           <nav className="App-nav">
             <Link to="/">Home</Link>
             <Link to="/profile">Profile</Link>

Create a Login/Logout Link

A pretty common scenario with authentication is having a button or link that you can click to log you in when you’re authenticated. You can use the same React Context to determine whether or not a user is logged in.

In order to properly log the user in or out when they click the link, you can wrap the component with withAuth to get access to the login and logout functions of auth.

This time, you don’t want the user to click either Login or Logout if you’re not sure what the state of authentication is yet. You could implement some sort of loading icon here, but for this demo just render nothing until you know whether or not the user is logged in.

src/LoginButton.js

import React from 'react';
import { withAuth } from '@okta/okta-react';

import Auth from './Auth';

export default withAuth(({ auth }) => (
  <Auth>
    {({ isAuthenticated }) => {
      if (isAuthenticated === null) return null;

      return (
        <a onClick={() => isAuthenticated ? auth.logout() : auth.login()}>
          {isAuthenticated ? 'Logout' : 'Login'}
        </a>
      );
    }}
  </Auth>
));

Now you can add the Login/Logout link to your list of nav items:

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -6,6 +6,7 @@ import logo from './logo.svg';
 import './App.css';

 import Auth from './Auth';
+import LoginButton from './LoginButton';

 const welcomeUser = ({ user }) => user
   ? `Welcome, ${user.given_name || user.name}!`
@@ -23,6 +24,7 @@ class App extends Component {
           <nav className="App-nav">
             <Link to="/">Home</Link>
             <Link to="/profile">Profile</Link>
+            <LoginButton />
           </nav>
         </header>
         <main className="App-intro">

Create a Real Profile Page

From the user value in your Context, you can also now get access to the user’s basic profile information.

Semantically, a dl HTML tag is a “Description List” element. This is a good, basic way to display metadata. However, you’ll probably want to add a little bit of simple styling. This will make sure the text isn’t center-aligned, and make the term (the dt tag) bold. Create a new file Profile.css that you’ll import in your profile page.

src/Profile.css

dl {
  text-align: left;
}

dt {
  padding: 4px 0;
  font-weight: bold;
}

Lodash provides a suite of utilities to manipulate data. To keep things simple and automated, try using that to convert the name of a key to something more personable. The startCase function will convert a string like given_name to Given Name. To add Lodash as a dependency, run the following:

yarn add [email protected]

The updated_at key is actually just a number representing the number of seconds from 1970, so you can convert that to a human-readable string in JavaScript using new Date(updated_at * 1000).toString().

Putting all that together, you can create a functional component that takes a user prop, and wrap that in the Auth Context Consumer. This time, show a simple loading message if the user isn’t loaded yet. Technically, the user will be undefined if authentication finished and there is no user, but because this is in a SecureRoute, if there is no user then the page will redirect to the home page.

src/Profile.js

import React, { Fragment } from 'react';
import { startCase } from 'lodash';

import Auth from './Auth';
import './Profile.css';

const ProfilePage = ({ user }) => {
  if (!user) return 'Loading...';

  return (
    <dl>
      {Object.keys(user).sort().map(key => (
        <Fragment key={key}>
          <dt>{startCase(key)}</dt>
          <dd>{key === 'updated_at' ? new Date(user[key] * 1000).toString() : user[key]}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

export default () => <Auth>{ProfilePage}</Auth>;

In your app’s routes, replace the mock profile page with a reference to the real one you just created:

--- a/src/App.js
+++ b/src/App.js
@@ -7,6 +7,7 @@ import './App.css';

 import Auth from './Auth';
 import LoginButton from './LoginButton';
+import ProfilePage from './Profile';

 const welcomeUser = ({ user }) => user
   ? `Welcome, ${user.given_name || user.name}!`
@@ -29,7 +30,7 @@ class App extends Component {
         </header>
         <main className="App-intro">
           <Route exact path="/" component={() => 'Home Page'} />
-          <SecureRoute exact path="/profile" component={() => 'Profile page'} />
+          <SecureRoute exact path="/profile" component={ProfilePage} />
           <Route path="/implicit/callback" component={ImplicitCallback} />
         </main>
       </div>

Now when you go to the profile page, you get some details about the logged in user.

Learn More

React Tutorial: Building and Securing Your First App

Simple User Authentication in React

React Router: Add the Power of Navigation

Learn React - React Crash Course 2019 - React Tutorial with Examples

React Hooks Tutorial for Beginners: Getting Started With React Hooks

Learn React.js for Beginners

React - The Complete Guide (incl Hooks, React Router, Redux)

Modern React with Redux [2019 Update]

React Native - The Practical Guide

MERN Stack Front To Back: Full Stack React, Redux & Node.js

Full-Stack Web Apps with Meteor and React

React Hooks