
ng-model , ngIf and ngFor . This code looks rather cumbersome. In React, on the other hand, JSX syntax is used, which is perceived as plain HTML, that is, in order to start React development, you do not need to learn fundamentally new things. Here's what it looks like: const Greetings = ({ firstName }) => ( <div>Hi, {firstName}</div> ); create-react-app package from Facebook to create the basis of the React application. This is probably the most popular approach to setting up the working environment, which allows you to start developing. Thanks to create-react-app programmer has at his disposal many of the necessary tools, which saves him from having to select them himself.create-react-app , use the following command: npm i -g create-react-app create-react-app react-intro cd react-intro npm start public/index.html . Here is what you see when you do this.
<div id="root"> . This is where our React application will be located. All this element will be replaced with the application code, and everything else will remain unchanged.src/index.js . This file performs the deployment of React-application. And, by the way, the source code of the application will be located in the src directory.
ReactDOM.render(<App />, document.getElementById('root')); App component (we'll talk about it very soon) and put it in the root div , which was defined in the index.html file we just reviewed.<App /> . It is very similar to HTML code, but it is a sample of JSX code that represents the special JavaScript syntax used by React. Please note that this construction starts with a capital A , that this is <App /> , not <app /> . This is because of the entity naming convention used in React. This approach allows the system to distinguish between ordinary HTML tags and React components. If component names do not begin with a capital letter, React will not be able to display them on the page..js file, you need to import React there using the following command: import React from 'react'; src/App.js
React.Component . This is exactly the task that the class App extends Component solves. All React components should contain an implementation of the render method, in which, as its name suggests, the component is rendered and its visual presentation is formed. This method should return HTML markup to display it on the page.className attribute is the equivalent of the class attribute in HTML. It is used to assign CSS class elements for styling. The class keyword in javascript is reserved; it cannot be used as an attribute name.A in the App ).React.Component class.render method that returns the markup.render method, then it is an excellent contender for processing it into a functional component. Armed with this idea, let's think about how to improve the App component created by the create-react-app tool: function App() { return ( <div className="App"> ... </div> ); } export default App; render method with the view structure function App() {...} . If we use the syntax of ES6 switch functions, then our code will look even better: const App = () => ( <div className="App"> ... </div> ); export default App; const Greetings = (props) => <div>Hey you! {props.firstName} {props.lastName}!</div>; const App = () => ( <div> <Greetings firstName="John" lastName="Smith" /> </div> ); Greetings component and used it to greet the person, whose name is John Smith , from the App component. All this code will result in the following HTML markup: <div> <div>Hey you! John Smith!</div> </div> {props.name} are used to extract JavaScript code. Greetings are passed to the firstName and lastName properties as parameters. We work with them by referring to the properties of the props object.props object is props , rather than two values ​​representing the properties firstName and lastName . const Greetings = ({ firstName, lastName }) => <div>Hey you! {firstName} {lastName}!</div>; (props) was replaced by ({ firstName, lastName }) . With this replacement, we inform the system that we are only interested in two properties of the props object. And this, in turn, allows us to directly access the values ​​of firstName and lastName , without explicitly specifying properties of an object like props.firstName .Greetings component code would look like this: class Greetings extends React.Component { render() { return ( <div>Hey you! {this.props.firstName} {this.props.lastName}!</div> ); } } this.props .Greetings and the App is in the same file. In practice, this should not be done, as this violates the SRP.Greetings component) need to be placed in separate files.Greetings component in a separate file: import React from "react"; const Greetings = ({ firstName, lastName }) => ( <div> Hey you! {firstName} {lastName}! </div> ); export default Greetings; App component: import Greetings from "./Greetings"; const App = () => ( ... ); App component code must be placed in the App.js file, the Greetings component code is in the Greetings.js file, and so on. import React from "react"; class SimpleForm extends React.Component { render() { return ( <div> <input type="text" name="firstName" /> <Greetings firstName="John" /> </div> ); } } const App = () => ( <div> <SimpleForm /> </div> ); John is always used as the username in the welcome page. What if so far not all our users call this? If so, then we put ourselves in a not very comfortable position. class SimpleForm extends React.Component { state = { firstName: "", }; onFirstNameChange = event => this.setState({ firstName: event.target.value }); render() { return ( <div> <input type="text" name="firstName" onChange={this.onFirstNameChange} /> <Greetings firstName={this.state.firstName} /> </div> ); } } SimpleForm component SimpleForm . In this object we add the property firstName .firstName field with an event handler. It starts every time the user enters at least one character in the field. In the class, the onChange property is responsible for handling the onChange onFirstNameChange , in the function representing which the command is executed of the following form: this.setState(...) setState method. In order to write a new value to the property firstName , we simply pass to this method an object containing what needs to be written to the state: { firstName: event.target.value } event.target.value is what the user entered in the form field, namely his name.onFirstNameChange as a method. It is very important that such things be declared in the form of class properties containing pointer functions, and not in the form of methods. If you declare a similar function as a method, then this will be bound to the form element that calls this method, and not to the class, as we might expect. This little thing is often confusing for beginners. This is one of the reasons for recommending the use of functional components, rather than component classes.onBlur event handler to the component, which is called when the user leaves the input field. Add another property to the application state - firstNameError . If an error occurred while entering the name, we will display a message about it under the field. class SimpleForm extends React.Component { state = { firstName: "", firstNameError: "", }; validateName = name => { const regex = /[A-Za-z]{3,}/; return !regex.test(name) ? "The name must contain at least three letters. Numbers and special characters are not allowed." : ""; }; onFirstNameBlur = () => { const { firstName } = this.state; const firstNameError = this.validateName( firstName ); return this.setState({ firstNameError }); }; onFirstNameChange = event => this.setState({ firstName: event.target.value }); render() { const { firstNameError, firstName } = this.state; return ( <div> <div> <label> First name: <input type="text" name="firstName" onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} /> {firstNameError && <div>{firstNameError}</div>} </label> </div> <Greetings firstName={firstName} /> </div> ); } } firstNameError to the state: state = { ... firstNameError: "", }; validateName arrow function. It checks the entered name with a regular expression: validateName = name => { const regex = /[A-Za-z]{3,}/; return !regex.test(name) ? "The name must contain at least three letters..." : ""; } onBlur look at the onBlur event onBlur , which is called when the user leaves the input field: onFirstNameBlur = () => { const { firstName } = this.state; const firstNameError = this.validateName( firstName ); return this.setState({ firstNameError }); }; firstName property from the state, taking advantage of ES6's ability to destruct the objects. The first line of this code is equivalent to: const firstName = this.state.firstName; firstName , and write to the state property firstNameError what this function returns. If the check fails, an error message will be sent to this property. If successful, an empty string will be written there.render() component method: render() { const { firstNameError, firstName} = this.state; ... } <input ... onBlur={this.onFirstNameBlur} /> onFirstNameBlur onBlur . {firstNameError && <div>{firstNameError}</div>} div , , , firstNameError true . render() { const { firstNameError, firstName } = this.state; return ( <div style={{ margin: 50, padding: 10, width: 300, border: "1px solid black", backgroundColor: "black", color: "white" }} > <div style={{marginBottom: 10}}> <label> First name: <input style={{backgroundColor: '#EFEFFF', marginLeft: 10}} type="text" name="firstName" onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} /> {firstNameError && <div style={{color: 'red', margin: 5}}>{firstNameError}</div>} </label> </div> <Greetings firstName={firstName} /> </div> ); } style .
render , , . Why is that bad? , . , , .style , . . , style.js : // style.js: const style = { form: { margin: 50, padding: 10, width: 300, border: "1px solid black", backgroundColor: "black", color: "white" }, inputGroup: { marginBottom: 10 }, input: { backgroundColor: "#EFEFFF", marginLeft: 10 }, error: { color: "red", margin: 5 } }; export default style; SimpleComponent : import style from './style'; class SimpleForm extends React.Component { ... render() { const { firstNameError, firstName } = this.state; return ( <div style={style.form}> <div style={style.inputGroup}> <label> First name: <input style={style.input} type="text" name="firstName" onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} /> {firstNameError && ( <div style={style.error}>{firstNameError}</div> )} </label> </div> <Greetings firstName={firstName} /> </div> ); } } export default SimpleForm; class SimpleForm extends React.Component { state = { ... lastName: "", lastNameError: "" }; validateName = ...; onFirstNameBlur = ...; onFirstNameChange = ...; onLastNameBlur = () => { const { lastName } = this.state; const lastNameError = this.validateName(lastName); return this.setState({ lastNameError }); }; onLastNameChange = event => this.setState({ lastName: event.target.value }); render() { const { firstNameError, firstName, lastName, lastNameError } = this.state; return ( <div style={style.form}> <div style={style.inputGroup}> <label> First name: <input style={style.input} type="text" name="firstName" onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} /> {firstNameError && <div style={style.error}>{firstNameError}</div>} </label> </div> <div style={style.inputGroup}> <label> Last name: <input style={style.input} type="text" name="lastName" onChange={this.onLastNameChange} onBlur={this.onLastNameBlur} /> {lastNameError && <div style={style.error}>{lastNameError}</div>} </label> </div> <Greetings firstName={firstName} lastName={lastName} /> </div> ); } } export default SimpleForm; firstName .render . .TextField , . import React from 'react' import style from "./style"; const TextField = ({name, onChange, onBlur, error, label}) => ( <div style={style.inputGroup}> <label> {label} <input style={style.input} type="text" name={name} onChange={onChange} onBlur={onBlur} /> {error && <div style={style.error}>{error}</div>} </label> </div> ); export default TextField; render . , , .SimpleForm : ... import TextField from './TextField'; class SimpleForm extends React.Component { ... render() { const { firstNameError, firstName, lastName, lastNameError } = this.state; return ( <div style={style.form}> <TextField name="firstName" label="First name:" onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} error={firstNameError} /> <TextField name="lastName" label="Last name:" onChange={this.onLastNameChange} onBlur={this.onLastNameBlur} error={lastNameError} /> <Greetings firstName={firstName} lastName={lastName} /> </div> ); } } TextField . FirstNameField : import React from 'react'; import TextField from './TextField'; const FirstNameField = ({...rest}) => ( <TextField name="firstName" label="First name:" {...rest} /> ); export default FirstNameField; ({...rest}) ( rest, ). , , , rest . , , TextField , « », spread (, {...rest} , ). rest , , TextField .FirstNameField TextField .LastNameField : ... import FirstNameField from './FirstNameField'; import LastNameField from './LastNameField'; class SimpleForm extends React.Component { ... render() { const { firstNameError, firstName, lastName, lastNameError } = this.state; return ( <div style={style.form}> <FirstNameField onChange={this.onFirstNameChange} onBlur={this.onFirstNameBlur} error={firstNameError} /> <LastNameField onChange={this.onLastNameChange} onBlur={this.onLastNameBlur} error={lastNameError} /> <Greetings firstName={firstName} lastName={lastName} /> </div> ); } } this , .
Source: https://habr.com/ru/post/428077/
All Articles