Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / React

Building ReactJs component And Integration of ReactJs with AngularJS.

4.67/5 (4 votes)
3 Jun 2015CPOL10 min read 31.5K  
Building ReactJs component And Integration of ReactJs with AngularJS.

Introduction

This article describes briefly

  1. How to build react components
  2. Communication between different react components
  3. Integration of AngularJS and React component.

Description

When to use React as a lifeline in Angular:

When it is time to render too many records e.g. more than 1000 rows using AngularJS, it always raises the question regarding its performance. Due to too many internal $watches and $digest cycle associated with each $scope value it always cost to performance of page.

The big rescue from it is ReactJS .

There is good post here by thierry.nicola where you can see that to render the 1500 rows using angularjs takes around 1.35 seconds while same for reactJS takes only around 310ms. By reading this great post you will clearly get idea of how fast react renders than Angular.

What we are going to cover in brief:

So in this post we are going to see how to build

  1. react components
  2. Communication between different react components
  3. Integration of AngularJS and React component.

NOTE: All the source code you can get from github here

To run the demo project read the instruction in README.md file in project folder.

ReactJS:

React component means to build reusable functionality .As in angularJs there is directive for this you can correlate directive to react component.

Means instead of directive we are going to use react component. We are going to use angular’s controller,factory and model but to display instead of directive we are using ReactJS.

Image 1

We are going to build image list in reactjs and will integrate this with AngularJS.

Each image and its associated functionality will form a child component in react and List of these child components will be a parent component of React.

Following page renders with image lists component integrated with AngularJS.

While starting to build any React component divide it into parent child hierarchy.

Image 2

So you can see we have divided our component into parent and child as shown in above fig(A).

React uses virtual DOM methodology to update DOM.

Virtual DOM:

virtual DOM is a JavaScript representation of the actual DOM; React keeps track of the differences between the current virtual DOM for current state, and previous virtual DOM for previous state. And update the actual DOM with only these differences.

JSX:

We are using JSX syntax to write code for react. JSX helps write HTML like syntax which gets transformed to lightweight JavaScript objects. You can get more idea for JSX from react documentation here

There are some basic building blocks which need to be consider while developing react

component as follows. Just have a look on it we will see what are those and how to use those.

Image 3Now we will analyze our parent component:

I have also placed the comments as well as comment box against code block to explore it more.

Kindly read both comment and comment boxes text to get the more clues.

ItemList.jsx (Parent Component)->

Image 4

Image 5

Image 6

propTypesTo put the constraint on type of receiving props in component from outside. You can also make it optional and required.

Some examples for propsType declaration:

  • React.PropTypes.array,
  • React.PropTypes.bool,
  • React.PropTypes.func,
  • React.PropTypes.number,
  • React.PropTypes.object,
  • React.PropTypes.string,
  • React.PropTypes.func.isRequired (Like we have declared in our code above)

Props: whatever the part of data is not going to update in component ,it will be used like read only then declare it in props.

In our example we are getting id,image url,name from JSON and we are using it as read only so we kept these under props.

Note: To access props always use this.props.propName.

State: whatever the part of data is going to update in component means it will be mutable for that respective component then it will fall under state.

Note: To access state always use this.state.stateName.

We are updating the string array of selectedItems which is nothing but a state of current component. As this is mutable object in component we have kept it as state.

getInitialState : It is used to provide the initial value to state or to initialize the state when component loads. Here we have initialized the selectedItems with empty array.

getDefaultProps: With this we can provide default values for receiving props if those are failed to supply from outside. We can have a look in above commented code as a reference for how to do that.

selectItems:This is the custom function we have declared for this component .We are updating our array(state) selectedItems in this method. We are sending as props to its child component as shown in above code and from child we are calling it to modify its state.

this.setState({ :It is used to update state of component and rerenders the respective component with updated state to reflect the modified state. We are calling this method in selectItems function to render component to reflect its updated state.

render: It is used to render your provided HTML mark up with your component in browser.

The actual use of render function is as follows:

React.render(<Component_Name />, document.body);

Component_Name: your declared react component using React.createClass method.

document.body:where to render it. Here you can place any html tag instead of body.

e.g. document.getElementById('Div_ID').

But in our case we are not providing second argument as we are going to render it using angular.

How it happens using angular that we will see sooooon !! J

In render function we iterated through received props (data )which is list of objects and passed it to child component Item and placed these child component one by one in <li> elements .Thus we have newly created object var products.

Code snippet:

Image 7

And in return function we just placed this products object which is having child component Item embedded in <li> elements in <ul> tag.

Code snippet:

Image 8

We have also used state selectedItems in <h3> tag to show clicked child components name.

HTML
<h3><div className="panel headerItem">selected  item :{ this.state.selectedItems.length>0?this.state.selectedItems.join(', '):"No Items yet" }</div></h3>

On clicking child component button “Change My status “ it will show the Item name in selected Items tag.On clicking again the same button it will remove the item name from selected Items tag.

Image 9

 

All this business logic is placed in selectItems function of parent component.

It receives the name of clicked item from child component, As we have seen that we already passed this function as a prop in child component. How to call it from child component that we will see now.

Item.jsx (Child Component)->

Image 10

Image 11

Image 12

Calling the current component ‘s function changeStatus on onClick. And in that function calling the parent component’s function selectitem which is received as props from parent component . this.props.selectitem(this.props.data.name) with argument.


This is how the call parent component method from child component and pass the parameter to it.

 

You can observe that we have passed two functions from paraent to child :

In parent :

HTML
<Item data={product} clickfunc={clickfunc} selectitem={selectItems} />

So in child components change status function we have called both of these received functions via props.

What clickfunc does :

It calls the angular controllers (MyCTRL ) function “ctrlFunc“.

Angular Side:

We have declared the controller myCTRL .

We also have created factory loadItems which used to load and return JSON file data.

In controller we created configuration object “config” which is having one function “ctrlFunc

And mydata variable in which JSON data is populated using factory.

e.g.:

//declaring the config object which would be latter passed to react component as prop.

$scope.config = {};

//Function declared on config object.
// Which will be called later from React component.

$scope.config.ctrlFunc=function() {
   alert("Method in controller called");
}

loadItems.LoadData().then(function (data) {
    data.forEach(function(d){ d.image = "../"+d.image });

    //populated the mydata variable of config object using factory.
    $scope.config.mydata = data;
});

ngReact: By using ngreact module we are going to do integration of angular and react.

More about the ngReact you can read it from here written by David Chang.

According to this there are 2 different ways to integrate React and Angular .

1. reactComponent 2. reactDirective

We are using one of ways called as reactDirective.

Code snippet from ngReact.js

return angular.module('react', [])
              .directive('reactComponent', ['$timeout', '$injector', reactComponent])
              .factory('reactDirective', ['$timeout','$injector', reactDirective]);
}));

reactDirective: It is angular factory which coverts your React component into angular directive.

We have mentioned its dependency in bower.json.

After downloading ngReact mark its dependency into your angular app as we done.

JavaScript
var app = angular.module('app', ['react']);

We are going to use parent component as angular’s directive so we have to pass it to ngReat’s

Factory to make it and use it as directive .

Image 13

 

Index.html:

Script dependency section:

<script src="../bower_components/angular/angular.js"></script>

<script src="../bower_components/angular-ui-router/release/angular-ui-router.js"></script>

<script src="../bower_components/react/react.js"></script>

<script src="../bower_components/react/JSXTransformer.js"></script>

<script src="../bower_components/ngReact/ngReact.js"></script>

<script src="item.jsx" type="text/jsx"></script>

<script src="itemList.jsx" type="text/jsx"></script>

<script src="app.js"></script>

Here's the file :

  1. <script src="../bower_components/react/JSXTransformer.js"></script> transforms your JSX code which is used to develop react component into plain javascript object.

  2. <script src="item.jsx" type="text/jsx"></script>
    <script src="itemList.jsx" type="text/jsx"></script> Here we have added both the components file into page.but plase note that src attribute here

is having .jsx extention not the .js extention. As we have used JSX syntax to write component.

Use of created itemlist directive :

<div id="itemslist" >

  <itemlist data="config" watch-depth="reference"/>

</div>
  1. You can see that we have provided our “config” object (declared on $scope)as a props value of component .
  2. Parent component is having data as its props which will populated as config object in that component.

3. That config object also consists of method “ctrlFunc” which will be get called from rect component. Thus we can also called controller function from react component.

Below is the flow of how controller function is propogated from angular to parent and parent to child component .

This is how the data along with its function flow from angular controller to react child component. And how the controller function get called from react child component.

Image 14

In this way we can pass data from angular controller to react component. And react parent component to its child component.

We can also use react’s own event to fetch data from outside.

Following are some of the frequently used events list:

  • componentWillMount – Fired before the component mount
  • componentDidMount – Fired after the component mounted
  • componentWillReceiveProps – Fired whenever there is a change to props
  • componentWillUnmount – Fired before the component unmounts.

To get the full control over data and we have also injected the function in config object supplied to data prop which will be work as callback /which will notify something in controller. So we have already created this object outside in the controller by fetching JSON data and then passed it to react.

It also helps for separation of concern.

You can use componentWillMount/ componentDidMount to get the data object in react component .

For more info about its implementation you can check following page from documentation:

For more info about its implementation you can check here .

Things to remember:

  1. You might have observed that I have commented the code in child component
JavaScript
render:function(){

    console.log("Child component called");

    var data=this.props.data;

    // data.image='../'+data.image;//great mistake  to modify prop here.so always 
    // modify object outside before passing it to

    // parent component.

Here we were modifying the image source to its correct location.

But as I already mentioned don’t modify the props ever. Because whenever there is this.state called component rerenders itself . So as we are modifying the props it will keep appending the previous modified values. You just uncomment the code and click the button multiple times and debug the data.image value.you will get this mistake immediately.

So we have already modified this props value in controller data before sending it to react.

JavaScript
loadItems.LoadData().then(function (data) {
    data.forEach(function(d){ d.image = "../"+d.image });
    //populated the mydata variable of config object using factory.

    $scope.config.mydata = data;

2. Also we have mentioned the console message both in parent and child component.

Parent component:

render: function() {

    console.log("Parent component called");

Child component:

render:function(){

console.log("Child component called");

It helps you to understand how the component get rerendered each time when this.setState called.

Just play with button “change my state” and see the how parent and child components get rerendered.How many times this message get logged in browser etc..

3. For the styling we have used here “className” to apply the css class and not the

only class with which we are familier. Kindly note this is how we can apply the css class to HTML elelments.

You can also provide the inline style as well.

To provide the inline style you need to declare style object inside the render function like bellow:

CSS
var myStyle = {

      color: ‘colorname’,

      fontSize: 10

    };

Key should follow the “camelCased” format .

And apply it as follow:

JavaScript
React.render(<div style={myStyle }>Hello World!</div>, HTML_Element_Object);

:) :) THANKS FOR READING !!!

Source code

You can download all source code from project hosted on my following github link

https://github.com/amit-ashtekar/ReactJS_AND_ReactJS_with_AngularJS

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)