📜 ⬆️ ⬇️

5 practical examples for studying the React framework

Translation of the article "5 Practical Examples For Learning The React Framework", Martin Angelov

You've probably heard about the popular JavaScript framework from Facebook - React . It is used on many popular websites, including Facebook and Instagram. In this article, you will see 5 practical examples built with React that will help you get started with this framework.

What is special about the React framework?


React is built on the concept of components. It differs from frameworks such as Angular or Ember, which use two-way data binding to update the HTML page. In my opinion, React is easier to learn than Angular or Ember - it is much smaller and works well with jQuery and other frameworks. It is also extremely fast, as it uses the virtual DOM and updates only the changed parts of the page (accessing the DOM is still the slowest part of modern web applications, which is why this framework gets a performance advantage by optimizing it).

However, the flip side of the coin is that in React you need a little more code to achieve things that can be easily written using data binding, as you can see in the examples below. For example, see our article on Angular .
')

How to use it?


To use React, you need to connect a single javascript file. Facebook graciously provides us with a CDN, which you can directly refer to:

<script src="http://fb.me/react-0.10.0.min.js"></script> 

This will give you access to the global React object, which contains many useful methods, some of which you can see in our examples. The recommended way to write web applications on React is using the JSX language. This is a slightly modified version of JavaScript that allows you to write React components using HTML-like syntax directly in your code. This code is compiled into JavaScript, before being interpreted by the browser. JSX is completely optional - you can use plain javascript if you prefer.

But stop banging, let's see some code!

1. Timer


As I mentioned earlier, the building blocks of the react applications are components. They are created by calling React.createClass() passing an object with properties and methods. Each component has a state (an object with data) and is responsible for its display — the render() method is called when the state changes. Here is an example of building a regular timer:

 /** @jsx React.DOM */ //    React.createClass. var TimerExample = React.createClass({ getInitialState: function(){ //     render.   //   this.state,      . return { elapsed: 0 }; }, componentDidMount: function(){ // componentDidMount  react',   //    .     : this.timer = setInterval(this.tick, 50); }, componentWillUnmount: function(){ //      ,    //    .     : clearInterval(this.timer); }, tick: function(){ //     50.   //   .  setState    this.setState({elapsed: new Date() - this.props.start}); }, render: function() { var elapsed = Math.round(this.state.elapsed / 100); //          dot (xx.x): var seconds = (elapsed / 10).toFixed(1); //      <p> , react   //   ,   seconds. return <p>This example was started <b>{seconds} seconds</b> ago.</p>; } }); React.renderComponent( <TimerExample start={Date.now()} />, document.body ); 
full JSFiddle example

When initializing a component, you can pass attributes with any JavaScript expressions by placing them in brackets {}. In this example, we supply the start date, which will be used each time the tick() function is called to calculate the elapsed seconds.

2. Navigation menu


Let's see how we can handle the click event in React - let's build the navigation menu:

 /** @jsx React.DOM */ var MenuExample = React.createClass({ getInitialState: function(){ return { focused: 0 }; }, clicked: function(index){ //     //       this.setState({focused: index}); }, render: function() { //     items,    // ,    var self = this; //  map     , //     <li> . return ( <div> <ul>{ this.props.items.map(function(m, index){ var style = ''; if(self.state.focused == index){ style = 'focused'; } //      bind().   // index    clicked: return <li className={style} onClick={self.clicked.bind(self, index)}>{m}</li>; }) } </ul> <p>Selected: {this.props.items[this.state.focused]}</p> </div> ); } }); //     ,      React.renderComponent( <MenuExample items={ ['Home', 'Services', 'About', 'Contact us'] } />, document.body ); 
full JSFiddle example

You probably noticed in the code of this example that we use attributes like className , which actually does not exist in HTML. This is due to the fact that when we return an element, we actually do not return HTML, but only an object of the React.DOM.p component. You can learn more about this at this link .

3. Instant Search


We have repeatedly been convinced that users do not like waiting. Here's how you can use React to build an instant search. (For comparison, see our version with AngularJS ).

 /** @jsx React.DOM */ //      var SearchExample = React.createClass({ getInitialState: function(){ return { searchString: '' }; }, handleChange: function(e){ //     ,      . //  ,   React',        //    .   ,  this.state.searchString. this.setState({searchString:e.target.value}); }, render: function() { var libraries = this.props.items, searchString = this.state.searchString.trim().toLowerCase(); if(searchString.length > 0){ // .  . libraries = libraries.filter(function(l){ return l.name.toLowerCase().match( searchString ); }); } return <div> <input type="text" value={this.state.searchString} onChange={this.handleChange} placeholder="Type here" /> <ul> { libraries.map(function(l){ return <li>{l.name} <a href={l.url}>{l.url}</a></li> }) } </ul> </div>; } }); var libraries = [ { name: 'Backbone.js', url: 'http://documentcloud.imtqy.com/backbone/'}, { name: 'AngularJS', url: 'https://angularjs.org/'}, { name: 'jQuery', url: 'http://jquery.com/'}, { name: 'Prototype', url: 'http://www.prototypejs.org/'}, { name: 'React', url: 'http://facebook.imtqy.com/react/'}, { name: 'Ember', url: 'http://emberjs.com/'}, { name: 'Knockout.js', url: 'http://knockoutjs.com/'}, { name: 'Dojo', url: 'http://dojotoolkit.org/'}, { name: 'Mootools', url: 'http://mootools.net/'}, { name: 'Underscore', url: 'http://documentcloud.imtqy.com/underscore/'}, { name: 'Lodash', url: 'http://lodash.com/'}, { name: 'Moment', url: 'http://momentjs.com/'}, { name: 'Express', url: 'http://expressjs.com/'}, { name: 'Koa', url: 'http://koajs.com/'}, ]; //   SearchExample   React.renderComponent( <SearchExample items={ libraries } />, document.body ); 
full JSFiddle example

This example also shows us another important concept in React - updating the state of our controller affects HTML, and not vice versa. In this example, as soon as you set the value of the text field, it will remain the same, not taking into account every keystroke, until you change it with the onChange event (you can change this behavior, but this is the recommended way to do these things).

4. Order Form


The real power of React appears when you combine several components. This allows you to better structure your code and introduce separation of duties. It also makes your code more easily used between different parts of your application. Here is an example of an order form that allows customers to plan their budget ( see the Angular version ):

 //    ,     - //       . var ServiceChooser = React.createClass({ getInitialState: function(){ return { total: 0 }; }, addTotal: function( price ){ this.setState( { total: this.state.total + price } ); }, render: function() { var self = this; var services = this.props.items.map(function(s){ //     Service    . // ,     self.addTotal function  . return <Service name={s.name} price={s.price} active={s.active} addTotal={self.addTotal} />; }); return <div> <h1>Our services</h1> <div id="services"> {services} <p id="total">Total <b>${this.state.total.toFixed(2)}</b></p> </div> </div>; } }); var Service = React.createClass({ getInitialState: function(){ return { active: false }; }, clickHandler: function (){ var active = !this.state.active; this.setState({ active: active }); //  ServiceChooser,   addTotal this.props.addTotal( active ? this.props.price : -this.props.price ); }, render: function(){ return <p className={ this.state.active ? 'active' : '' } onClick={this.clickHandler}> {this.props.name} <b>${this.props.price.toFixed(2)}</b> </p>; } }); var services = [ { name: 'Web Development', price: 300 }, { name: 'Design', price: 400 }, { name: 'Integration', price: 250 }, { name: 'Training', price: 220 } ]; //  ServiceChooser      React.renderComponent( <ServiceChooser items={ services } />, document.body ); 
full JSFiddle example

The first problem that arises when combining several components is how to allow them to communicate with each other. The first way is to transfer the necessary data to the attributes when they are initialized. This only works if the components “from parent to child” communicate. To communicate in the other direction, you can pass one of the methods of the parent component as an attribute to the child component. The child component can then call this method and inform the parent of the events. You can read about it here .

5. Application with images on AJAX


This example will show how you can combine react with jQuery, and how to load results with AJAX. While frameworks like Angular have their own approaches for working with AJAX, React allows you to use any library you prefer to work with ( see Angular version ).

 /** @jsx React.DOM */ //         -     //    Instagram  AJAX. var Picture = React.createClass({ //       -    //       . clickHandler: function(){ //   ,   onClick, //      : this.props.onClick(this.props.ref); }, render: function(){ var cls = 'picture ' + (this.props.favorite ? 'favorite' : ''); return ( <div className={cls} onClick={this.clickHandler}> <img src={this.props.src} width="200" title={this.props.title} /> </div> ); } }); var PictureList = React.createClass({ getInitialState: function(){ //      AJAX,  //  ,    : return { pictures: [], favorites: [] }; }, componentDidMount: function(){ //   ,  jQuery AJAX  var self = this; //   API,      var url = 'https://api.instagram.com/v1/media/popular?client_id=' + this.props.apiKey + '&callback=?'; $.getJSON(url, function(result){ if(!result || !result.data || !result.data.length){ return; } var pictures = result.data.map(function(p){ return { id: p.id, url: p.link, src: p.images.low_resolution.url, title: p.caption ? p.caption.text : '', favorite: false }; }); //   .   render. // ,      pictures //     . self.setState({ pictures: pictures }); }); }, pictureClick: function(id){ // id  ID  . //    pictures      var favorites = this.state.favorites, pictures = this.state.pictures; for(var i = 0; i < pictures.length; i++){ //      if(pictures[i].id == id) { if(pictures[i].favorite){ return this.favoriteClick(id); } //     , //  ,  : favorites.push(pictures[i]); pictures[i].favorite = true; break; } } //  ,   this.setState({pictures: pictures, favorites: favorites}); }, favoriteClick: function(id){ //         //          ,  -. var favorites = this.state.favorites, pictures = this.state.pictures; for(var i = 0; i < favorites.length; i++){ if(favorites[i].id == id) break; } //    favorites.splice(i, 1); for(i = 0; i < pictures.length; i++){ if(pictures[i].id == id) { pictures[i].favorite = false; break; } } //     this.setState({pictures: pictures, favorites: favorites}); }, render: function() { var self = this; var pictures = this.state.pictures.map(function(p){ return <Picture ref={p.id} src={p.src} title={p.title} favorite={p.favorite} onClick={self.pictureClick} /> }); if(!pictures.length){ pictures = <p>Loading images..</p>; } var favorites = this.state.favorites.map(function(p){ return <Picture ref={p.id} src={p.src} title={p.title} favorite={true} onClick={self.favoriteClick} /> }); if(!favorites.length){ favorites = <p>Click an image to mark it as a favorite.</p>; } return ( <div> <h1>Popular Instagram pics</h1> <div className="pictures"> {pictures} </div> <h1>Your favorites</h1> <div className="favorites"> {favorites} </div> </div> ); } }); //   PictureList     body. //   API    Instagram . // ,       http://instagram.com/developer/ React.renderComponent( <PictureList apiKey="642176ece1e7445e99244cec26f4de1f" />, document.body ); 
full JSFiddle example

Note that our example uses the same Picture component to display a list of all and selected images. Such reuse is one of the advantages for organizing your code into components.

What's next?


React allows you to structure your application transparently and encourages code reuse. And thanks to the power of the virtual dom, the framework can significantly speed up complex interfaces. React is suitable for rendering on the server side as well as on the client side and makes it possible to build isomorphic applications that can easily be transferred from client to server.

But there is much more to learn about react. I suggest starting from here:

Source: https://habr.com/ru/post/229629/


All Articles