Social Network System with React JS Part One
Wall Script
Follow Me:
Sunday, August 14, 2016

Social Network System with React JS Part One

How to solve infinity loading either in your desktop or mobile? By now, everyone is familiar with JQuery, but we all know is JQuery cannot handle such large amount of data to load. React JS is the best solution for this problem. JQuery and other libraries interacts directly with DOM to load any data; but React JS is specifically designed in such a way that it has a mid interactive layer called Virtual DOM which in turn interacts with DOM(as shown in the diagram below). This Virtual DOM helps in data loading very faster.

Social Network System with React JS


Download Script     Live Demo

React is a big library; Initially, for the developers it may look bit complicated to code using React JS, but eventually we feel it very easy once we get used to it. React is easy to maintain too. I specifically suggest React JS for mobile applications. Applications like Facebook, twitter uses React. React JS is not a framework, its a library for View component. Take a look at the demo, how React works for our Wall System.

How to Start React Application
You have to include following libraries to start React application, React is using JSX(Javascript with XML on it) standard and it is not a globally accepted standard, so we are using Babel compiler browser.min.js and JavaScript code type should be "text/babel"
<!DOCTYPE html>
<html lang="en">
<head>
<title>React JS</title>
 <link rel="stylesheet" href="css/wall.css" />
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="build/browser.min.js"></script>
</head>
<body>
<div id="container"></div>
</body>
<script type="text/babel">
// React Code ....
</script>
</html>

Hello World
React structure for printing value in HTML DOM.
<script type="text/babel">
ReactDOM.render(
  <div>Hello World</div>,
  document.getElementById('container')
);
</script>

Hello World Component
React is all about components, here is the stucture for HelloWorld component. Component name must start with capital letter.
<script type="text/babel">
var HelloWorld=React.createClass({
    render: function(){
    return(
   <div>Hello World</div>
    );
   }
});

ReactDOM.render(
  <HelloWorld/>,
  document.getElementById('container')
);
</script>

Getting started with Wall System - Step 1
Hope you like my previous post Angular JS Facebook Wall System with Multiple Bindings, just follow the tutorial for HTML & CSS design for Wall System.
<script type="text/babel">
var WallContainer=React.createClass({
   render: function(){
    return(
    <div id="wallContainer">
     <h1>Social Network System with React JS Demo</h1>
     <WallFeed/>
    </div>
    );
   }
});

ReactDOM.render(
  <WallContainer/>,
  document.getElementById('container')
);
</script>

Create a main component called WallContainer, this is going to render within HTML ID container. Included a new component called WallFeed

WallFeed Component
This component divided into two components WallFrom & WallUpdated.
var WallFeed=React.createClass({
  render: function(){
  return(
      <div>
      <WallForm/>
      <WallUpdates />
      </div>
  );
  }
});

WallForm
This contains wall update form operations.
var WallForm=React.createClass({
  render: function(){
  return(
    <form >
    <textarea></textarea>
    <input type='submit' value='Post' id='wallPost'/>
    </form>
  );
  }
});

Status Update Box

WallUpdates
This component contains wall updates operation, follow the steps you will find more about this.
var WallUpdates=React.createClass({
 render: function(){
  return(
   <div id="wallFeed">
      //News Feed Uploads Loop
     </div>
  );
  },
});

news feed updates

Include Jquery for Ajax Calls
You have to include Jquery library for ajax features to communicate with APIs or server side operations.
<script src="build/jquery.min.js"></script>
<script src="build/ajaxPostReact.js"></script>

ajaxPostReact.js
Create a simple Jquery ajax function for reusability, this will minimize your code.
function ajaxPostReact(url, dataPost, reactThis, success)
{
  $.ajax({
type:"POST",
url: url,
data:dataPost,
dataType:"json",
cache:false,
timeout:20000,
beforeSend :function(data) { }.bind(this),
success:function(data){success.call(this, data);}.bind(this),
error:function(data){}.bind(this)
  });
}

Load User Updates Data to WallFeed Component
Now go to WallFeed component and include following functions. Here getInitialState and componentDidMount are React builtin functions. Using getInitialState you can initialize variables and componentDidMount is loads with component.
var WallFeed=React.createClass({
 getInitialState: function(){
   return {data: []};
  },
 updatesFromServer: function()
  {
    var dataPost='';
    var reactThis=this;
    ajaxPostReact('newsFeed.php', dataPost, reactThis, function(data){
    reactThis.setState({data: data.updates});
    });
  },
  componentDidMount: function()
  {
this.updatesFromServer();
  },
  render: function(){
  return(
      <div>
      <WallForm/>
      <WallUpdates data={this.state.data}/>
      </div>
  );
  }
});

updatesFromServer function is contains ajax operation to load user updates data, using this.state assigning updates data to the WallUpdates component.

Read more about Create a RESTful services using Slim and Wall Database Design

JSON Response newsFeed.php
Following JSON data we need to render with WallUpdates component.
{
  "updates": [
    {
      "user_id": "1",
      "name": "Srinivas Tamada",
      "profile_pic": "pic.png",
      "update_id": "62",
      "user_update": "The Wall Script http://www.thewallscript.com",
      "created": "1464062121",
      "comments": [
        {
          "com_id": "62",
          "uid_fk": "80",
          "comment": "Nice",
          "created": "1468871427",
          "like_count": "0",
          "name": "Arun Shekar",
          "profile_pic": "pic.jpg",
          "timeAgo": "2016-07-18T21:50:27+02:00"
        },
        //Other Comments
      ]
    },
   //Other Udates
  ]
}

WallUpdates Rendering with User Updates Data
Now go to WallUpdates component and modify in following way, using this.props calling the WallUpdates component state value.
var WallUpdates=React.createClass({
render: function(){
var updatesEach=this.props.data.map(function(update, index)
{
return(
<div className="feedBody" key={update.created}>
<img src={update.profile_pic} className="feedImg" />
<div className="feedText">
<b>{update.name}</b>
<a href="#" className="feedDelete">X</a>
{update.user_update}    
</div>
//Comments Block
</div>
)
}, this);
return(
<div id="wallFeed">
{updatesEach}
</div>
);
},
});

Step 1 Demo

Step 2

WallForm
Using findDOMNode focusing textarea box ref value updateInput.
var WallForm=React.createClass({
  getInitialState: function(){
  return { user_update: ''};
  },
  componentDidMount: function(){
    ReactDOM.findDOMNode(this.refs.updateInput).focus();
  },
  render: function(){
  return(
    <form >
    <textarea ref="updateInput" value={this.state.user_update}></textarea>
    <input type='submit' value='Post' id='wallPost'/>
    </form>
  );
  }
});

Getting Update Box Input Value
Write a function get the input state value using e.target.value. Set user_update value using React.setState function.
updateChange: function(e){
  this.setState({user_update: e.target.value });
 }

onChange Input
Every input change triggers updateChange function.
<textarea ref="updateInput" value={this.state.user_update
onChange={this.updateChange}></textarea>

Update Form Input Submit
Now include updateSubmit value to validate user input.
updateSubmit: function(e){
    e.preventDefault();
    var user_update= this.state.user_update.trim();
    if(!user_update)
    {
      return;
    }
    else
    {
      console.log("Send user_update value to WallUpdates component");
      this.setState({  user_update: ''});
    }
}

Include about function at form onSubmit action.
<form onSubmit={this.updateSubmit} >
<textarea ref="updateInputvalue={this.state.user_update
onChange={this.updateChange}></textarea>
<input type='submit' value='Post' id='wallPost'/>
</form>

Step 2 Demo

Step 3
Back to WallFeed Component
Include updateAjaxSubmit for ajax operation.
var WallFeed=React.createClass({
updateAjaxSubmit: function(update)
{
    var reactThis=this;
    ajaxPostReact('updateFeed.php', update , reactThis, function(data){
       var updates = reactThis.state.data;
       var newUpdates = [data.updates[0]].concat(updates);
       reactThis.setState({data: newUpdates});
    });
},
render: function(){

}
});

Create an attribute onUpdateSubmit, call the updateAjaxSubmit function.
<WallForm onUpdateSubmit={this.updateAjaxSubmit}/>

updateFeed.php
JSON response for user update.
{
  "updates": [
    {
      "user_id": "7",
      "username": "rajesh",
      "name": "Rajesh Tamada",
      "profile_pic": "pic.png",
      "update_id": "1470950004",
      "user_update": "User update value",
      "created": "1470950004",
      "comments": []
    }
  ]
}

WallForm Component
Now replace console.log with onUpdateSubmit, this will set user_update data to WallUpdates component state.
updateSubmit: function(e){
    e.preventDefault();
    var user_update= this.state.user_update.trim();
    if(!user_update)
    {
      return;
    }
    else
    {
     this.props.onUpdateSubmit({ user_update: user_update});
     this.setState({  user_update: ''});
    }
}

Step 3 Demo

Step 4

textToLink.js
Create a JavaScript function for filtering HTML tags and converting text to link using regular expressions.
function textToLink(text)
{
var finalText=text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/gi;
var htmlData=finalText.replace(urlPattern, '<a target="_blank" href="$&">$&</a>');
return htmlData;
}

Include this with in the HEAD tag
<script src="build/textToLink.js"></script>

Create a textToLinkHTML function in WallUpdates component.
var WallUpdates=React.createClass({
 textToLinkHTML: function(content){
  var finalContent=textToLink(content);
  return {__html: finalContent}
 },
render: function(){
var updatesEach=this.props.data.map(function(update, index)
{
return(
<div className="feedBody" key={update.created}>
<img src={update.profile_pic} className="feedImg" />
<div className="feedText">
<b>{update.name}</b>
<a href="#" className="feedDelete">X</a>
<span dangerouslySetInnerHTML={this.textToLinkHTML(update.user_update)}  />   
</div>
//Comments Block
</div>
)
}, this);
return(
<div id="wallFeed">
{updatesEach}
</div>
);
},
});

Now replace {update.user_update} in following way.
{update.user_update}
to
<span dangerouslySetInnerHTML={this.textToLinkHTML(update.user_update)}  />   

Step 4 Demo

Step 5 - Delete User Update

WallFeed Component
Create a delete update function, this will handle delete operation based on the update_id
deleteUpdate: function(e)
{
var updateIndex=e.target.getAttribute('value');
var update_id=e.target.getAttribute('data');
var data='updateID='+update_id;
var reactThis=this;
ajaxPostReact('deleteUpdate.php', data , reactThis, function(data){
  reactThis.state.data.splice(updateIndex,1);
  reactThis.setState({data: reactThis.state.data});
});
}

Create an attribute deleteUpdate and assign deleteUpdate ajax function.
<WallUpdates data={this.state.data}/>
to
<WallUpdates data={this.state.data} deleteUpdate={this.deleteUpdate}/>

WallUpdates Component
Assign deleteUpdate function to X hyperlink onClick
<a href="#" className="feedDelete">X</a>
to
<a href="#" className="feedDelete" value={index} data={update.update_id} 
onClick={this.props.deleteUpdate} >X</a>

Step 5 Demo

Next Part: Wall System Comment System with React JS Part Two

Was this article helpful?
Thanks! Your feedback helps us to improve 9lessons.info


11 comments:

  1. in component wall feed method deleteUpdate

    e.target.value failed to work i had to change it to e.target.getAttribute('data')

    ReplyDelete
  2. Hello! Link to Part 2 doesn`t work

    ReplyDelete
  3. Replace

    e.target.value
    to
    e.target.getAttribute('value')

    ReplyDelete
  4. zipped file is wrong. It downloads the angularWall.zip and contains angular.js files.

    ReplyDelete
  5. Why you include whole jQuery library for only ajax calls? This is waste of bytes

    ReplyDelete

Make in India