React is a Frontend Framework. It's an open source project that started at Facebook and it's maintained by developers at Facebook and Instagram and also a huge community of contributors. React is intended to be the view or the user interface, the V in MVC. One of the benefits and goals of the React project is to make developing a large scale single page application or SPA, much easier.
React doesn’t use a Shadow Dom, instead it provides the ability to create your own components that you can later reuse, combine, and integrate. The ease in which this occurs will boost productivity in development.
Rather than utilizing the browsers DOM, React utilizes a virtual DOM stored in memory, then will inject said modifications to the rendered DOM.
React utilizes a special syntax called JSX, which will allow you to mix HTML and JavaScript. It isn’t a requirement, but allows a cleaner approach to writing components. JSX utilizes the familiarity of XML Syntax.
Reading and writing to the DOM is slow. Reading and writing to JavaScript objects is faster. The React virtual DOM is a JavaScript object. React never reads from the real DOM, and it only writes to the real DOM if needed.
Let's take a closer look at how this works...
Whenever you use functions like getElementById or using a jQuery object like: $(‘#Example’), you're reading from the DOM. When you change any of those elements, change classes, change content, you're writing to the DOM. So you reading and you writing to the DOM will tax site performance.
When looking at closer other at other frameworks we will typically see slow DOM rendering (EX: Backbone or knockout). Typically they re-render the same data over and over again. Even when changes haven't happened everywhere, we continue to re-render, then re-render, and re-render...
So why is React so fast? React only interacts it's 'virtual' DOM, (that is a JavaScript object). When we use getDOMNode, we'll get state information from the virtual DOM. When we call the render function, React will update the virtual DOM which will push only those necessary changes to the real DOM.
Razor and React both appear to be identical (not really but, Greg is making a point), both will convert the after mentioned code into a literal translation for the browser to interpret.
The primary problem with Razor, unless the View State is precompiled performance can become an issue as the View State is rendered. This disconnect stems from Razor converting into C#, then into IL, then into the browser. The content isn’t truly dynamic, as it needs to be re-rendered into the View State.
React isn’t a full framework, there isn’t a router, controller, model management, or other prebuilt functionality like a other MVC approaches. This limitation is alleviated with Flux, designed to create a clear connection between all aspects within the framework.
The primary difference being Views don’t modify data directly. All modifications of the data are done by triggering Action Events. Since it’s an application architecture, there’s really not a pro or con. Use of it will depend highly on your needs.
One reason why I would use the Flux pattern would be to avoid handling imperative UI state changes, whenever my data has changed.
If I were to delete a to-do, in a to-do list application. It’s going to be a hassle if I need to imperatively update the UI state in other places such as the List of to-do’s, total to-do’s count.
var FirstComponent = React.createClass({ propTypes: { name: React.PropTypes.string.isRequired, location: React.PropTypes.string.isRequired }, getDefaultProps: function() { return { name: 'Mike', location: 'Tigard' } }, render: function() { let name = this.props.name; let location = this.props.location; return ( <div> <p>Hello, {name}!</p> <p>I live in {location}</p> </div> ) } }); // FirstComponent.propTypes = { // name: React.PropTypes.number // } ReactDOM.render( <FirstComponent name="Greg" location="Beaverton"/>, document.getElementById('app') );
var CounterChallenge = React.createClass({ getInitialState: function() { return { count: 0 } }, incrementCount: function(value) { this.setState({ count: this.state.count + value }) }, getDefaultProps: function() { return { valueOne: 1, valueTwo: 5, valueThree: 10, text: 'Add' } }, alert: function() { alert('Button Clicked') }, render: function() { return ( <div className="container"> <h1>Count: {this.state.count}</h1> <Button style="btn blue-btn" text={`${this.props.text} ${this.props.valueOne}`} value={this.props.valueOne} clickHandler={this.incrementCount.bind(this, this.props.valueOne)} /> <Button style="btn green-btn" text={`${this.props.text} ${this.props.valueTwo}`} value={this.props.valueTwo} clickHandler={this.incrementCount.bind(this, this.props.valueTwo)} /> <Button style="btn purple-btn" text={`${this.props.text} ${this.props.valueThree}`} value={this.props.valueThree} clickHandler={this.incrementCount.bind(this, this.props.valueThree)} /> <Button text="Alert!" clickHandler={this.alert} /> </div> ) } }); var Button = function(props) { return ( <button className={props.style} value={props.value} onClick={props.clickHandler}>{props.text}</button> ) }; ReactDOM.render( <CounterChallenge valueOne={100} valueTwo={1000} valueThree={10000}/>, document.getElementById('app') );
var TaskList = React.createClass({ getInitialState: function() { return { tasks: [ {title: 'Finish Mobile 1.5', id: 1}, {title: 'Finish plat.com 1.5', id: 2}, {title: 'Conquer the world', id:3} ] } }, render: function() { return ( <ul> {this.state.tasks.map(function(task) { return <Task title={task.title} key={task.id} /> })} </ul> ) } }); var Task = function(props) { return ( <li>Task: {props.title}</li> ) }; ReactDOM.render( <TaskList />, document.getElementById('app') )
```javascript let BaseCount = (BasicComponent) => class extends React.Component { constructor(props) { super(props); this.state = { count: 0, text: "Hello" } this.incrementCount = this.incrementCount.bind(this); } incrementCount() { this.setState({ count: this.state.count + 1 }) } render() { return ( <div className="container"> <BasicComponent {...this.state} increment={this.incrementCount}/> </div> ) } } const Button = (props) => { console.log(props) return ( <button className="btn blue-btn" onClick={props.increment}>Count: {props.count}</button> ) } const Label = (props) => { return ( <label onMouseMove={props.increment}>Count: {props.count} </label> ) } let ExtendedButton = BaseCount(Button); let ExtendedLabel = BaseCount(Label); const Container = () => { return( <div> <ExtendedButton /> <ExtendedLabel /> </div> ) } ReactDOM.render( <Container />, document.getElementById('app') ); ```