Integration with C# and ReactJS

The goal for this project is to show a list of books with ReactJS from a WebAPI written in C#. You can download this project from Github.

New project

Start by creating a new ASP.NET MVC 4 project: 1. File → New → Project 2. Select ".NET Framework 4" and Templates → Visual C# → Web → ASP.NET MVC 4 Web Application. Call it "CSReact" 3. In the "New ASP.NET MVC 5 (or 4) Project" dialog, select the MVC (or empty) template.

Install ReactJS.NET

We need to install ReactJS.NET to the newly-created project. This is accomplished using NuGet, a package manager for .NET. Right-click on the "ReactDemo" project in the Solution Explorer and select "Manage NuGet Packages". Search for "ReactJS.NET" and install the ReactJS.NET (MVC 4 and 5) package.

Create basic controller and view

Right-click on the Controllers folder and click Add → Controller. Name the controller "HomeController" and select "Empty MVC Controller" as the template. Once the controller has been created, right-click on return View() and click "Add View". Enter the following details:

  • View name: Index
  • View Engine: Razor (CSHTML)
  • Create a strongly-typed view: Unticked
  • Create as a partial view: Unticked
  • Use a layout or master page: Unticked

Replace the contents of the new view file with the following:

@{
    ViewBag.Title = "Home Page";
}
@section featured {
    <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <h1>@ViewBag.Title.</h1>
                <h2>@ViewBag.Message</h2>
            </hgroup>
            <p>
            </p>
        </div>
    </section>
}
<h3>React here:</h3>
<div id="content"></div>

@section scripts {
    <script src="https://fb.me/react-0.14.0.min.js"></script>
    <script src="https://fb.me/react-dom-0.14.0.min.js"></script>
    <script src="@Url.Content("~/Scripts/pages/books.jsx")"></script>
}

We also need to create the referenced JavaScript file books.jsx. Right-click on Scripts folder, select Add > New Folder, and enter "pages" as the folder name. Once created, right-click on the folder and select Add > New Item. Select Web > JavaScript File, enter "books.jsx" as the file name, and click "Add".

Create a model

Under Models folder add a new class called BookModels with the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CSReact.Models {
   /// <summary>
   /// Book models
   /// </summary>
   public class BookModels {
      /// <summary>
      /// Title of the book
      /// </summary>
      public string Title { get; set; }

      /// <summary>
      /// Author of the book
      /// </summary>
      public string Author { get; set; }
   }
}

Generate WebAPI for Books

To generate a WebAPI right-click on Controllers folder and then you select Add → Controller. Choose now WebAPI 2 Controller - Empty and type Books. The API name will be BooksController.

Fill in the controller the following code:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Script.Serialization;
using CSReact.Models;
using Newtonsoft.Json.Serialization;

namespace CSReact.Controllers
{
    public class BooksController : ApiController
    {
       public HttpResponseMessage Get() {
          IList<BookModels> result = new List<BookModels>();
          result.Add(new BookModels() { Author = "Michael Crichton", 
                                        Title = "Jurassic Park" });
          result.Add(new BookModels() { Author = "Agatha Christie", 
                                        Title = "And Then There Were None" });

          var formatter = new JsonMediaTypeFormatter();
          var json = formatter.SerializerSettings;

          json.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
          json.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
          json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
          json.Formatting = Newtonsoft.Json.Formatting.Indented;
          json.ContractResolver = new CamelCasePropertyNamesContractResolver();
          json.Culture = new CultureInfo("en-GB");

          return Request.CreateResponse(HttpStatusCode.OK, result, formatter);
       }
    }
}

This API reply on your local server. You can call your API with an URL similar to

http://localhost:60273/api/books

and the result in the browser is a json result

[
  {
    "title": "Jurassic Park",
    "author": "Michael Crichton"
  },
  {
    "title": "And Then There Were None",
    "author": "Agatha Christie"
  }
]

Generate a book list

In the books.jsx file write the following code:

var BookList = React.createClass({
    render: function() {
        var bookNodes = this.props.data.map(function (book) {
            return (
                <div>
                    {book.title} ({book.author})
                </div>
            );
        });

        return (
            <div className="bookList">
                {bookNodes}
            </div>
        );
    }
});

This function will receive as a property data. data will contain the list of books that it has read from our WebAPI. For each row in data (you can read for each book in data), it creates a new div with title and author from book. The function returns a new div within the list of book.

Then we can write the other part of the books.jsx where you read the data from the WebAPI and display it calling BookList function. The complete code of books.jsx is

var BookList = React.createClass({
    render: function() {
        var bookNodes = this.props.data.map(function (book) {
            return (
                <div>
                    {book.title} ({book.author})
                </div>
            );
        });

        return (
            <div className="bookList">
                {bookNodes}
            </div>
        );
    }
});

var App = React.createClass({
    getInitialState: function() {
        return {data: []};
    },

    componentDidMount: function() {
        $.get(this.props.url, function(result) {
            var book = result[0];
            if (this.isMounted()) {
            }
        }.bind(this));
    },

    componentWillMount: function() {
        var xhr = new XMLHttpRequest();
        xhr.open('get', this.props.url, true);
        xhr.onload = function() {
            var jdata = JSON.parse(xhr.responseText);
            this.setState({ data: jdata });
        }.bind(this);
        xhr.send();
    },

    render: function() {
        return (
          <div className="commentBox">
            <BookList data={this.state.data} />
          </div>
      )
    }
});

ReactDOM.render(
  <App url="/api/books/Get" />,
  document.getElementById('content')
);

If you're lucky and try to start your app, you can see the list of books in your index page.

ReactJS: component Lifecycle and Rendering

These are the functions that will be, or can be, included in your specification object when you’re creating a component. Part of these specification functions are lifecycle functions, which when encountered, will show the details as to when they execute during the life of a component.

Function invocation order during the initial render of a React component

Function_invocation_order_during_the_initial_render_of_a_React_component

Component lifecycle that happens when the state changes on a component

Component_lifecycle_that_happens_when_the_state_changes_on_a_component

Lifecycle of a component when it has altered props

Lifecycle_of_a_component_when_it_has_altered_props

render

Every React component must have a render function. This render function will accept a ReactElement and provide a container location where the component will be added or mounted to the DOM.

getInitialState

This function will return an object. The contents of this object will set the state of the component when it initially renders. This function is invoked one time, just before the component renders. When creating a component using ES6 classes, you will actually be setting the state, via this.state, within the constructor function of the class.

getDefaultProps

When a ReactClass is first created, getDefaultProps is invoked one time and then is cached. This function returns an object that will represent the default state of this.props on the component. Values for this.props that do not exist in the parent component, but are present in the component’s mapping, will be added to this.props here. When you’re creating a component using the ES6 setting, the default props is done within the constructor function of your component class.

Mixins

A mixin in the component specification is an array. A mixin can share the lifecycle events of your component and you can be assured that the functionality will execute during the proper time during the component’s lifecycle. An example mixin is a timer control that merges the lifecycle events of a SetIntervalMixin with the main component called TickTock.

Example of Mixin in jsfiddle

displayName

displayName is a property that is used when you see debugging messages from your React app.

componentWillMount

componentWillMount is a lifecycle event that React uses during the process of taking your component class and rendering it to your DOM. The componentWillMount method is executed once before the initial render of your component. The unique thing about componentWillMount is that if you call your setState function within this function, it will not cause a re-render of your component because the initial render method will receive the modified state.

componentWillMount()

componentDidMount

componentDidMount is a function that’s invoked only on the client side of React processing, after the component has been rendered to the DOM. At this point, the React component has become a part of the DOM and you can access it using the React.findDOMNode function.

componentDidMount()

componentWillReceiveProps

componentWillReceiveProps is executed when the component will be receiving props. This function is invoked every time that there is a prop change, but never on the first render. You can call setState inside this function and you will not cause an additional render. The function that you provide will have an argument for the next props object that is going to become part of the component’s props. Within this function though you still have access to the current props using this.props so you can make any logic comparisons between this.props and nextProps in this function.

componentWillReceiveProps( nextProps )

shouldComponentUpdate

This function is invoked before a component renders and each time a change in prop or state is received. It will not be called before the initial render, or when forceUpdate is utilized. This function is a mechanism that you can use to skip rendering if you know that the changes to the props or state will not actually require the component to update. To short-circuit the render process, you need to return false in the function body, based on whatever criteria you determine. Doing this will bypass the rendering of the component, by not only skipping the render() function but also the next steps in the lifecycle — componentWillUpdate and componentDidUpdate

shouldComponentUpdate( nextProps, nextState );

componentWillUpdate

componentWillUpdate is invoked right before a render occurs on your component. You cannot use setState in this function.

componentWillUpdate( nextProps, nextState )

componentDidUpdate

componentDidUpdate is executed just after all the rendering updates are processed into the DOM. Since this is based on an update, it is not part of the initial render of the component. The arguments available to this function are the previous props and previous state.

componentDidUpdate( prevProps, prevState );

componentWillUnmount

When a component is rendered to the DOM, it is called mounting. It follows then that this function componentWillUnmount would be invoked immediately before the component is no longer going to be mounted to the DOM.

componentWillUnmount()

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  September 2017  >>
MonTueWedThuFriSatSun
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

View posts in large calendar

Month List