📜 ⬆️ ⬇️

Learning React - for what, where, how?

How to start learning a new library or freymorka? Immediately find an article on Habré and headlong into the abyss of practical examples? Or, first carefully examine the official and unofficial documentation, before moving on to practice? It is between these questions that your mind will rush when you decide to find out what ReactJS is. To the desire to learn is not dead, like the famous donkey, be sure to look under the hood.

Prepare a sleigh in the summer and a cart in the winter


Few people think about how the finished application will work on the combat server. Usually these issues are solved at the very end, when the code is already written, and there is no going back. That is why, before you start studying the library itself, decide on the issues of compiling the code of your future creation. There are two options here. For study, or, say, a demo site, the option of compiling on the client side. You don’t need to do anything, the browser will do everything for you, on the fly, so to speak. But for the finished product, I would advise to set up a compilation on the server side. The benefit of tools for this abound. Then you and Babel , and NodeJS or Webpack .

Childhood, childhood where did you go


Well, with the compilation issues figured out. Let's go to study? No, it's too early. React implements a modular approach for building applications. What does it mean? Imagine a constructor. Not the constructor inside the class, but a simple children's constructor. Just like you built your masterpieces from small blocks as a child, you will build an application from React components. So it is even more interesting to play, since you yourself also create the components. The beauty of the modular approach is that by creating and testing such a component once, you can easily use it in your other applications. Therefore, my advice to you is: create separate files for each of them, and then just plug in the right place. It seems simple, but it is not quite so. An application is empty, dead, if its components do not “communicate” with each other. And this is precisely the most difficult and interesting.

Well, let me work!


I see that your desire to learn melts before your eyes. Therefore, open the documentation and move from words to action. All that we need for study is on the official website of the library. True information is poorly structured. Helping you not get lost in this chaos is the main task of this article.
As you already understood, the main task in developing applications for React is to break the page into blocks and create components that would implement the functionality of each of them.
First, create a “static” version of your component. Highly recommend paying attention to JSX .
')
var LoginForm = React.createClass({ render: function() { return ( <form id="login-form"> <input type="text" id="login" placeholder="login" /> <input type="password" id="password" placeholder="password" /> <button type="submit">Login</button> </form> ) } }); React.render( <LoginForm />, document.getElementById('example')); 

Appreciate the benefits of jsx syntax? Then we go further. Add a bit of "interactivity." The component interface will be redrawn automatically if any data inside this component changes. These include:


Therefore, it all comes down to a banal change of state or properties in response to user actions.

 var LoginForm = React.createClass({ getInitialState: function(){ /*    */ return { errorCode: 0, errorMessage: '', loginActions: [] }; }, doLogin: function(event) { event.preventDefault(); var successLogin = (Math.random() >= 0.5) ? true : false; var actions = this.state.loginActions; if (!successLogin) { actions.push('Login failure'); /*       */ this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions}); } else { actions.push('Login success'); this.setState({errorCode: 0, errorMessage: '', loginActions: actions}); } }, render: function() { /*      */ var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : ''; var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'}; return ( <div> <form id="login-form"> <div> <input type="text" id="login" placeholder="login" /> <input type="password" id="password" placeholder="password" /> </div> <div> <button type="submit" onClick={this.doLogin}>Login</button> </div> <div style={errorStyle}> <span style={{color: '#d9534f'}}> {errorMessage}</span> </div> </form> <div className="actions-list"> /*      actions */ <ActionsList actions={this.state.loginActions} /> </div> </div> ) } }); var ActionsList = React.createClass({ render: function() { /* ,      this.props */ return ( <ol> { this.props.actions.map(function(action) { return <li>{action}</li>; }) } </ol> ) } }); React.render( <LoginForm />, document.getElementById('example')); 

As you already understood, React is significantly different from other libraries. Therefore, there is nothing surprising in the fact that when working with form elements there are also features that can add you a fair amount of gray hair on your head. Form elements are divided into two types:


Let's set the initial value for the input elements, and try to enter something:

 <input type="text" id="login" placeholder="login" value=”admin” /> <input type="password" id="password" placeholder="password" value=”admpass” /> 

As you can see, we did not succeed. Now React “controls” these elements and we need to write our own change handlers for them. Imagine how much work it is, to write handler functions for each of the controlled elements? Mom do not worry! But the good uncles from Facebook did not leave us in trouble and added the ability to use mixins in React. Yes, and a few good additions (addons) tossed.

 var LoginForm = React.createClass({ /*   */ mixins: [React.addons.LinkedStateMixin], getInitialState: function(){ return { errorCode: 0, errorMessage: '', loginActions: [], defaultLogin: 'admin', defaultPassword: 'password' }; }, doLogin: function(event) { event.preventDefault(); var successLogin = (Math.random() >= 0.5) ? true : false; var actions = this.state.loginActions; if (!successLogin) { actions.push('Login failure'); this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions}); } else { actions.push('Login success'); this.setState({errorCode: 0, errorMessage: '', loginActions: actions}); } }, render: function() { var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : ''; var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'}; return ( <div> <form id="login-form"> <div> /*        valueLink */ <input type="text" ref="login" placeholder="login" valueLink={this.linkState('defaultLogin')} /> <input type="password" ref="password" placeholder="password" valueLink={this.linkState('defaultPassword')} /> </div> <div> <button type="submit" onClick={this.doLogin}>Login</button> </div> <div style={errorStyle}> <span style={{color: '#d9534f'}}> {errorMessage}</span> </div> </form> <div className="actions-list"> <ActionsList actions={this.state.loginActions} /> </div> </div> ) } }); var ActionsList = React.createClass({ render: function() { return ( <ol> { this.props.actions.map(function(action) { return <li>{action}</li>; }) } </ol> ) } }); React.render( <LoginForm />, document.getElementById('example')); 

If you think that there are no more "surprises", then you are very much mistaken. Here's a problem for you: how to organize bidirectional data exchange between components? After all, properties are transmitted only in one direction - from father to descendants. And vice versa? How can a descendant influence the data of its parent? Very simple:

 var LoginForm = React.createClass({ mixins: [React.addons.LinkedStateMixin], getInitialState: function(){ /*  ,      ,  ,   loginActions */ return { errorCode: 0, errorMessage: '', loginActions: [], defaultLogin: 'admin', defaultPassword: 'password' }; }, clearActionList: function() { /*      ,   loginActions */ this.setState({loginActions: []}); }, doLogin: function(event) { event.preventDefault(); var successLogin = (Math.random() >= 0.5) ? true : false; var actions = this.state.loginActions; if (!successLogin) { actions.push('Login failure'); this.setState({errorCode: 1, errorMessage: 'Error while login.', loginActions: actions}); } else { actions.push('Login success'); this.setState({errorCode: 0, errorMessage: '', loginActions: actions}); } }, render: function() { var errorMessage = (this.state.errorCode > 0) ? this.state.errorMessage : ''; var errorStyle = (this.state.errorCode > 0) ? {display: 'block'} : {display: 'none'}; return ( <div> <form id="login-form"> <div> <input type="text" ref="login" placeholder="login" valueLink={this.linkState('defaultLogin')} /> <input type="password" ref="password" placeholder="password" valueLink={this.linkState('defaultPassword')} /> </div> <div> <button type="submit" onClick={this.doLogin}>Login</button> </div> <div style={errorStyle}> <span style={{color: '#d9534f'}}> {errorMessage}</span> </div> </form> <div className="actions-list"> /*       ,   ,    */ <ActionsList actions={this.state.loginActions} clearActions={this.clearActionList} /> </div> </div> ) } }); var ActionsList = React.createClass({ render: function() { return ( <div> /*      ,    - this.props.clearActions */ <button onClick={this.props.clearActions}> Clear list </button> <ol> { this.props.actions.map(function(action) { return <li>{action}</li>; }) } </ol> </div> ) } }); React.render( <LoginForm />, document.getElementById('example')); 

Cause time, fun hour!


Here you go. Now really everything. The first stage is over and I am glad to welcome you to the ranks of the newly-made reactors. Whether ReactJS is worth the time spent on it - everyone decides for himself. Passed only half way. For some, this road was easy, for someone - not very. Someone will go on, and someone to stop. And I really hope that my article will be a good help to newbies.

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


All Articles