How to interact with input in Reactjs


With Browser route we can create beautiful responsive React app on the go. Most of the dynamic applications accepts some feed back from users. How do we get this done.

This will involve the following

  • Setting state for the each input element.
  • Attach it to the value property of the input.
  • Add a button event function and attach it to the render method.

Setting State

I have a one input text field and a button in the component.

import React, { Component } from "react"; 
 
class Comment extends Component {
  constructor(props) {
    super(props);    
    this.state = {      
    };
  }
  
  
  render() {
    return (
      <div className="form-group  m-2 p-2">
        <textarea
          placeholder="Comment here"
          class="form-control"          
          aria-describedby="inputSuccess5Status"
        />
        <button
          className="btn btn-primary m-1 p-2"        >
          Comment
        </button>         
      </div>
    );
  }
}

export default Comment;

In the above Comment component I have used bootstrap to beautify the form with one Text Area and button element. We need to create and attach a state for the Text Area in the constructor, also need to attach the new value with the state, whenever the user enter the comment. So we need to setState the comment in the on Change event handler.

  • Create state
  • Create event handler for on Change
  • attach them to the HTML tags
class Comment extends Component {
  constructor(props) {
    super(props);
    this.onChangeComment = this.onChangeComment.bind(this);
    this.onPostComment = this.onPostComment.bind(this);
     
    this.state = {
      comment: "",
    };
  }
  onChangeComment(e) {
    this.setState({ comment: e.target.value });
  }

  onPostComment(e) {
    try {
      
     console.log('Thank for using react form')
    } catch (error) {
      console.log(error);
    }
  }
  
  render() {
    return (
      <div className="form-group  m-2 p-2">
        <textarea
          placeholder="Comment here"
          class="form-control"
          value={this.state.comment}
          onChange={this.onChangeComment}
          aria-describedby="inputSuccess5Status"
        />
        <button
          className="btn btn-primary m-1 p-2"
          onClick={this.onPostComment}
        >
          Comment
        </button>
         <CommentCard  comments={this.props.comments}/>
      </div>
    );
  }
}

In the above code , created a state comment , event handlers for input and button and bind them in the constructor.

In the on Change event update the state so, each time the user update will change the state.

Finally attach the state and handlers to form elements ( button,Text Area).

Where did can I see the log(‘…’) result ?. well ,open your browser , ctrl+shift+I ( for developer tools) then go to console and you will see the message)

Following React posts deserve good read

How to render mongo object in Reactjs


MongoDB objects are object Id of another document stored in the mongo database. Following is our sample mongo document we want to render in our React front end.

{    
    "_id": "5fef1f5087a69346300003a7",
    "title": "Title post",
    "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
    "user": {    
        "_id": "5fe4ab1e69b8d525c44ec293",
        "name": "admin",
        "createdAt": "2020-12-24T14:52:14.364Z",
        "updatedAt": "2021-01-01T13:12:59.084Z",
        "__v": 106
    },
    "createdAt": "2021-01-01T13:10:40.468Z",
    "updatedAt": "2021-01-01T13:10:41.907Z",
    "__v": 3
}

Our task is to render the user object and access its properties

For simplicity I skip the rest of the component code.

render() {
    return (
      <div>
        <div className="card m-2 p-2">
          <h3>{this.state.post.title}</h3>
          <div>{this.state.post.content} </div>
          <div>  Posted By: {Object(this.state.post.user).name}            
     </div>
        </div>
      </div>
    );

React recognize sub document as filed, not as an object. So we have to convert the user to Object ( the highlighted line)

So far we have succeeded to render the MongoDB object

Following React posts deserve good read

How to render mongo document in Reactjs


MongoDB documents are are similar to rows in a relational database and collection as Table .Following is our sample mongo document we want to render in our React front end.

{    
    "_id": "5fef1f5087a69346300003a7",
    "title": "Title post",
    "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
    "user": {    
        "_id": "5fe4ab1e69b8d525c44ec293",
        "name": "admin",
        "createdAt": "2020-12-24T14:52:14.364Z",
        "updatedAt": "2021-01-01T13:12:59.084Z",
        "__v": 106
    },
    "createdAt": "2021-01-01T13:10:40.468Z",
    "updatedAt": "2021-01-01T13:10:41.907Z",
    "__v": 3
}

We need to get rendered the post in a React component . To do this we need to do the following

  • Make API call – fetching the post
  • Save the object to state
  • Type cast the object and render

For simplicity I skip the rest of the component code.

State and API Call

....
constructor(props) {
    super(props);

    this.state = {
      post: Object,
   
    };
  }
.....

componentDidMount() {
    const { pid } = this.props.match.params;

    axios
      .get(`http://localhost:3005/post/${pid}`)
      .then((res) => {
        if (res.data) {
          this.setState({ post: res.data});
        }
      })
      .catch((error) => {
        console.log(error);
      });
 
  }

render() {
    return (
      <div>
        <div className="card m-2 p-2">
          <h3>{this.state.post.title}</h3>
          <div>{this.state.post.content} </div>
                 
     </div>
        </div>
      </div>
    );

Our API call return a single post, a mongo document , Note that we initialized the post (parent document) with Object in the constructor.

The data returned by the response object ( post) is a React acceptable object, so we can render it directly without any pain .

In this tutorial you have learned

  • Read parameter list from URL in React
  • API call in React
  • Render mongo document

Following React post/project deserve your attention

How to render list of mongo objects in React component


We have already learned how to create mongo objects and array of objects, I put links below in case you need them.

Suppose we have the following document with array of tags which is a collection MongoDB objects. Our task is that render the list in the component.

{
    
    "tags": [
        {
            "posts": [
                "5fef1f5087a69346300003a7"
            ],
            "_id": "5fef1f5187a69346300003a8",
            "tagName": "Test",
            "createdAt": "2021-01-01T13:10:41.799Z",
            "updatedAt": "2021-01-01T13:10:41.855Z",
            "__v": 1
        },
        {
            "posts": [
                "5fef1f5087a69346300003a7"
            ],
            "_id": "5fef1f5187a69346300003a9",
            "tagName": "VM",
            "createdAt": "2021-01-01T13:10:41.804Z",
            "updatedAt": "2021-01-01T13:10:41.896Z",
            "__v": 1
        },
        {
            "posts": [
                "5fef1f5087a69346300003a7",
                "5fef1f7287a69346300003af",
                "5ff12f993ddcac34903623cd"
            ],
            "_id": "5fef1f5187a69346300003aa",
            "tagName": "JS",
            "createdAt": "2021-01-01T13:10:41.810Z",
            "updatedAt": "2021-01-03T02:44:43.120Z",
            "__v": 3
        }
    ],
    "_id": "5fef1f5087a69346300003a7",
    "title": "Title post",
    "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
    "user": {        
        "_id": "5fe4ab1e69b8d525c44ec293",
        "name": "admin",
        "createdAt": "2020-12-24T14:52:14.364Z",
        "updatedAt": "2021-01-03T02:44:41.780Z",
        "__v": 108
    },
    "createdAt": "2021-01-01T13:10:40.468Z",
    "updatedAt": "2021-01-03T02:37:55.982Z",
    "__v": 11
}

How to access the list in React

It is best practice to store the list as separate state in a React component and not to access is directly as {post.tags.map(element=>().

Accessing the tags list using post.tags.map(element=>() cause Type and map error.

State

Add the state and from the API calls method ( I used the componetDidmount method) . I skipped the portion of component for simplicity

//contructor 
constructor(props) {
    super(props);

    this.state = {
      post: Object,
      tags: [],
      comments: [],
    };
  }

.....
.....
componentDidMount() {
    const { pid } = this.props.match.params;

    axios
      .get(`http://localhost:3005/post/${pid}`)
      .then((res) => {
        if (res.data) {
          this.setState({ post: res.data, tags: res.data.tags ,});
        }
      })
      .catch((error) => {
        console.log(error);
      });

       const id =`http://localhost:3005/comment/${pid}`
       
     axios
       .get(id)
       .then((response) => {        
         this.setState({comments:response.data})
       })
       .catch((e) => {
         console.log(e);
       });
  }

Rendering the List

We are ready to render the list inside <div> tags state using a the map with key.

{this.state.tags.map((element) => (
              <span
                className="badge badge-info m-1"
                key={element._id.toString()}
              >                
                {element.tagName}{" "}
              </span>
            ))}

we had successfully rendered the list of mongo objects.

Following React posts may help you

How to place custom route links in Reactjs component


Suppose you have a React application which uses link to navigate another route/page. How do we place the link ? . Let’s look at the post example.

const PostTitles= props=>(
  <div>
    <div>Date: {props.post.createdAt} </div>    
    <a href=`/post/${props.post._id}` >{props.post.title} </a>
  </div>
)

In the above code is a part of blogging web app, which consists of posts,uers,comments and tags components. In PostTitles component which shows title link of posts we used back tick ( `) to add variable. The back tick inside the render part may not work perfectly as in JavaScript.

Solution

So to make it work we have to add pair of extra curly braces ({}) as follows

const PostTitles= props=>(
  <div>
    <div>Date: {props.post.createdAt} </div>    
    <a href={`/post/${props.post._id}`} >{props.post.title} </a>
  </div>
)

Following React posts may help you

How to fix mongo object Type error in Reactjs


MongoDB objects are object Id of another document stored in the mongo database. Following is our sample mongo document we want to render in our React front end.

{    
    "_id": "5fef1f5087a69346300003a7",
    "title": "Title post",
    "content": "It is a good practice to keep styles for different pages  in separate style sheets. Larger project this becomes more applicable. What you do when need to combine them in another ?",
    "user": {    
        "_id": "5fe4ab1e69b8d525c44ec293",
        "name": "admin",
        "createdAt": "2020-12-24T14:52:14.364Z",
        "updatedAt": "2021-01-01T13:12:59.084Z",
        "__v": 106
    },
    "createdAt": "2021-01-01T13:10:40.468Z",
    "updatedAt": "2021-01-01T13:10:41.907Z",
    "__v": 3
}

In the above document we want to render the user object and the following code will cause an type error

For simplicity I skip the rest of the component code.

render() {
    return (
      <div>
        <div className="card m-2 p-2">
          <h3>{this.state.post.title}</h3>
          <div>{this.state.post.content} </div>
          <div> Posted By: {(this.state.post.user).name}            
     </div>
        </div>
      </div>
    );

TypeError: Cannot read property ‘name’ of undefined

Error Fix

React recognize sub document as filed, not as an object.To fix the error we have to convert the user to Object as follows.

render() {
    return (
      <div>
        <div className="card m-2 p-2">
          <h3>{this.state.post.title}</h3>
          <div>{this.state.post.content} </div>
          <div>  Posted By: {Object(this.state.post.user).name}            
     </div>
        </div>
      </div>
    );

Following React posts may help you

How to create multi page app with Reactjs


Reactjs is UI library for Nodejs web projects which offer responsive web application. By default Reactjs project is one page application. You may wonder is all the React apps is one page apps ? No chance.

A route is a web page in a website / web app. A standard web app is consisting of many routes such as Home/Index Page, About, Contact etc

Routes

What is a route ? A route is a web page in a website / web app. A standard web app is consisting of many routes such as Home/Index Page, About, Contact etc. Each page has different content. If you were familiar with Python Flask app development, things becomes crystal clear.

How to create routes in React

To turn the one page Reactjs app into multi page app we have to use the BrouwserRouter and Router from the react-router-dom module.

import {BrowserRouter as Router,Route} from 'react-router-dom'
import  './bootstrap/dist/css/bootstrap.min.css'
import Home from './components/home.component'
import About from "./components/about.component";

function App() {
  return (
    <Router>
      <div className="container">  
      <br/>
      <Route path="/" exact component={Home}/>       
      <Route path="/about" exact component={About}/>
      </div>
       
    </Router>
  );

In the above example , we had created two routes with component, one for Home page and another for About Page.

The Route component is used to create new page in our app. The route has path and component props.

The path is used to define the route, ‘/’ is used for the default, which is used none of route is specified in the URL such as

http://localhost:3001

component define the Reactjs component is being used in the route which can be defined in a separate file, usually under Component folder.

That is all you need, following React post deserve your attention

How to make GET API request in Reactjs


We have already learn about how to make API calls in HTML using jQuery and AJAX , if you do miss the article here is the quick link to the posts.

React

React is a JavaScript UI library for building super responsive web application. We can connect React with Nodejs-Express API/ any API (already covered the API creation with Node-Express in the past tutorials, following links will be helpful for revisiting those posts)

Create API with Node-Express

GET API call with Axios

Axios is a NPM package which let you use API in react. To use axios we have to install the package and make API request. The GET can be used to the fetch the data from the server.

A GET request is used to fetch data from the server, for example retrieve a set of products from the server based on user query

componentDidMount() {
   axios
    .get("http://localhost:3005/post/find")
    .then((response) => {
     
       if (response.data.length > 0) {
         this.setState({
           posts: response.data ,
        });
      }
    })
    .catch((error) => {
       console.log(error);
    });
}

In the above code we have make call to the API end point post/find which will pull out all the posts from the server. Since it is a collection we have checked for the array length to make sure the data retrieved. Also note that the best place to call API is componentDidiMount method which is a react lifecycle method.

componentDidiMount is one of the lifecycle method Reactjs had which automatically called before displaying components on the UI

Following react posts help you to build better React apps

How to make POST API request in Reactjs


We have already learn about how to make API calls in HTML using jQuery and AJAX , if you do miss the article here is the quick link to the posts.

React

React is a JavaScript UI library for building super responsive web application. We can connect React with Nodejs-Express API/ any API (already covered the API creation with Node-Express in the past tutorials, following links will be helpful for revisiting those posts)

Create API with Node-Express

POST API call with Axios

Axios is a NPM package which let you use API in react. To use axios we have to install the package and make API request.

npm i --save axios

A POST request is used to pass data to the server, for example register a new product to the inventory

onPublish(e) {
    e.preventDefault();
    const post = {
      title: this.state.title,
      content: this.state.content  
    };
    console.log(post);
    axios
      .post("http://localhost:3005/post/create", post)
      .then((res) => console.log(res.data))
      .catch((error) => {
        console.log(error);
      });
  }

In the above code we have make call to the API end point post/create which will save the post to the server.

Following React API posts help you to build better React apps

Create a login Form component in Reactjs


React allow us to create reusable component using either class / functional component feature.

login Form component

Our login form make use of the following techniques

  • Callback ref
  • CSS – in React
  • class component
  • props – function passing
  • Property access through refs

Class components

We have two class component one for Login form itself and another for the container Form. The loginform component have the following structure.

import React, { Component } from "react";
import "./assets/style.css";

class LoginForm extends Component {
 constructor(props) {
   super(props);
   this.cbNameRef = null;
   this.cbPassRef = null;
   this.setCbPass = (element) => {
     this.cbPassRef = element;
  };

   this.setCbName = (element) => {
     this.cbNameRef = element;
  };
}

 componentDidMount() {
   if (this.cbNameRef) {
     this.cbNameRef.focus();
  }
}
 reSet = () => {
   if (this.cbNameRef) {
     this.cbNameRef.focus();
     this.cbNameRef.value = "";
     this.cbPassRef.value = "";
  }
};

 render() {
   return (
     <div className="login">
       <label id="align-left" for="uname">
        User Name
       </label>
       <input className="box" id="uname" type="text" ref={this.setCbName} />
       <br />
       <label id="align-left" for="pass">
        Password
       </label>
       <input className="box" id="pass" typ="password" ref={this.setCbPass} />
       <div className="buttonsWrapper">
         <div class="btnWrapper">
           <button
             className="LoginBtnWrapper btnStyle"
             onClick={this.props.loginHandler}
           >
            Login
           </button>
         </div>
         <div class="btnWrapper">
           <button className="ResetBtnWrapper btnStyle" onClick={this.reSet}>
            Reset
           </button>
         </div>
       </div>
     </div>
  );
}
}
export default LoginForm;

Refs

I have used two callbackRefs in this component namely , cbNameRef, cbPassRef which allow us to access the value from another component. The first ref also used to set the focus. The componentDidmount lifecycle method help us to set the primary focus to the name box.

There is also corresponding setMethods for refs for attaching the ref with input fields. The reSet arrow function is for resetting the form ( which only needed within the accessibility of the component)

You also note that the login button handler is not specified, it have to passed through the props of the component from the parent.

If you are not familiar with refs, I suggest you two of the following articles

Using callbackref for accessing DOM object in Reactjs - How to access the DOM using callBackref in Reactjs
Accessing the value of input in Reactjs - How to access the value of input using ref in reacrjs
Accessing the DOM in Reactjs - How to access DOM directly in Reactjs

The Form component

The second component is a Form, which is the container. This component need to interact with login Form. So we need to access the property of the other component. Ref made it possible.

In the Form component we have

  • A event handler
  • Ref
import React, { Component } from "react";
import LoginForm from "./LoginForm";

class Form extends Component {
 constructor(props) {
   super(props);
   this.callBackRef = null;
   this.setCbRef = (element) => {
     this.callBackRef = element;
  };
}

 loginHandler = () => {
   alert("User :" + this.callBackRef.cbNameRef.value);
};
 render() {
   return (
     <div>
       <LoginForm ref={this.setCbRef} loginHandler={this.loginHandler} />
     </div>
  );
}
}

export default Form;

Using the callBackRef we can access the ref of the login Form class without any issue. In fact we can even call the reSet method of the Login Form from the container using this.callBackRef.reSet() which is not required for the functionality of our component.

CSS

We have utilized CSS for styling the form, if you are not familiar with CSS take a look at the CSS styling post.

How to use CSS styles in Reactjs - How to use CSS styles in Reactjs

You can include CSS style code in a file ending with .css extension and then import it to your module, I hope the above post will help you to understand CSS in React.

That’s all. You can find the complete project @ GitHub Repository