1. Introduce the React

React is a JavaScript library for building user interfaces. It only takes care of the view layer of an application, helping developers build fast and interactive Web applications.

React uses components to build the user interface.

2. The JSX syntax

React uses the JSX syntax, which is a JavaScript syntax extension, to describe the user interface.

Before the React code executes, Babel converts JSX syntax to standard JavaScript apis.

JSX syntax is a syntactic sugar that lets developers build user interfaces with more comfortable code.

2.1 Using expressions in JSX

const user = { firstName: 'Harper', lastName: 'Perez' } function formatName(user) { return user.firstName + ' ' + user.lastName; } const element = <h1>Hello, {formatName(user)}! </h1>;Copy the code

JSX itself is an expression that can be assigned to a variable, passed in as a parameter, or returned as a value.

function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}! </h1>; } return <h1>Hello, Stranger.</h1>; }Copy the code

2.2 attributes

If the attribute value is a string, quotation marks are required, and camel name is recommended.

const element = <div greeting="hello"></div>;
Copy the code

If the property value is a JavaScript expression, parentheses surround the property value.

const element = <img src={user.avatarUrl} />; // Note that no quotation marks can be placed around braces. JSX will recognize the contents of quotation marks as strings, not expressionsCopy the code

2.3 JSX single mark must be closed

If JSX is a single tag, it must be closed or an error is reported.

const element = <img src={user.avatarUrl} />
const element = <input type="text"/>
Copy the code

2.4 the className

To add a class name to a JSX tag, use className instead of class.

const element = <img src={user.avatarUrl} className="rounded"/>;
Copy the code

2.5 JSX automatically expands arrays

Const ary = [<p> ha </p>, <p> ha </p>, <p> ha </p>]; const element = ( <div>{ary}</div> ); / / resolved / * < div > < p > haha < / p > < p > haha < / p > < p > hey hey < / p > < / div > * /Copy the code

2.6 Ternary Operation

{ boolean ? <div>Hello React</div> : null }
{ boolean && <div>Hello React</div> }
Copy the code

2.7 cycle

Const persons = [{id: 1, name: 'zhang ', age: 20}, {id: 2, name:' Wang ', age: 22}]Copy the code
<ul>
  { persons.map(person => <li key={person.id}> {person.name} {person.age} </li>) }
</ul>
Copy the code

2.8 event

<button onClick={this.eventhandler}> button </button> {/* Need to pass the event object */} <button OnClick ={e=> this.eventhandler ('arg',e)}> button </button> {/* The last argument is the event object does not need to pass */} <button OnClick ={this.eventhandler. bind(null, 'arg')}> </button>Copy the code
constructor () { this.eventHandler = this.eventHandler.bind(this) } eventHandler () {} <button Button onClick = {this. EventHandler} > < / button >Copy the code

2.9 style

2.9.1 Inline styles
class App extends Component {
  render() {
    const style = {width: 200, height: 200, backgroundColor: 'red'};
    return <div style={style}></div>
  }
}
Copy the code
2.9.2 Outer chain style
// Button.js import styles from './Button.module.css'; class Button extends Component { render() { return <button className={styles.error}>Error Button</button>; }}Copy the code
2.9.3 Global Style
import './styles.css'
Copy the code

2.10 ref attribute

2.10.1 createRef
class Input extends Component {
  constructor() {
    super()
    this.inputRef = React.createRef()
  }
  render() {
    return (
      <div>
        <input type="text" ref={this.inputRef} />
        <button onClick={() => console.log(this.inputRef.current)}> button </button>
      </div>
    )
  }
}
Copy the code
2.10.2 Function Parameters
class Input extends Component {
  render() {
    return (
      <div>
        <input type="text" ref={input => (this.input = input)} />
        <button onClick={() => console.log(this.input)}>button</button>
      </div>
    )
  }
}
Copy the code
2.10.3 ref String

This command is not recommended. Errors are reported in strict mode.

class Input extends Component {
  render() {
    return (
      <div>
        <input type="text" ref="username" />
        <button onClick={() => console.log(this.refs.username)}>button</button>
      </div>
    )
  }
}
Copy the code
2.10.4 Obtaining Component Instances

Click the button to get focus for the Input text box.

The Input text box and the method to get the focus of the text box are defined in the Input component, the input component is introduced in the App component, and the button is defined in the App component.

// Input.js class Input extends Component { constructor() { super() this.inputRef = React.createRef() this.focusInput = this.focusInput.bind(this) } focusInput() { this.inputRef.current.focus() } render() { return ( <div> <input type="text"  ref={this.inputRef} /> </div> ) } }Copy the code
// App.js
class App extends Component {
  constructor() {
    super()
    this.InputComponentRef = React.createRef()
  }
  render() {
    return (
      <div className="App">
        <Input ref={this.InputComponentRef} />
        <button onClick={() => this.InputComponentRef.current.focusInput()}>button</button>
      </div>
    )
}
Copy the code

3. The component

3.1 What is a component

React takes a component-based approach to user interface development. A component can be thought of as an encapsulation of an area of a page.

3.2 Creating Components

3.2.1 Creating Class Components
import React, { Component } from 'react'; Class App extends Component {render () {return <div>Hello, I </div>}}Copy the code
3.2.2 Creating function components
Const Person = () => {return <div>Hello, I'm a functional component </div>; }Copy the code

Matters needing attention

  1. The component name must start with an uppercase letter to distinguish a component from a common label.
  2. The JSX syntax outer layer must have a root element

3.3 components props

3.3.1 Props Pass data

When calling a component, you can pass data inside the component, where you can get data passed in from outside through the Props object.

< Person name = "George" age = "20" / > < Person name = "Mary" age = "10" / >Copy the code
Class Person extends Component {render() {return (<div> <h3> name: {this.props. Name}</h3> <h4> age: {this.props.age}</h4> </div> ); }}Copy the code
// Const Person => {return (<div> <h3> name: {props. Name}</h3> <h4> age: {props. }Copy the code

Note:

  1. The data stored in the props object is read-only and cannot be modified inside the component.
  2. After the data in the props data source is modified, the data received in the component is updated synchronously. (Data-driven DOM)
3.3.2 Setting the default value of props
class App extends Component {
    static defaultProps = {}
}
Copy the code
function ThemedButton(props) {
}
ThemedButton.defaultProps = {
  theme: "secondary",
  label: "Button Text"
};
Copy the code
3.3.3 component children

The props. Children property is used to get the content to populate the inside of the component tag when the component is called.

Contents inside the <Person> component </Person>Copy the code
const Person = (props) => {
    return (
    	<div>{props.children}</div>
    );
}
Copy the code
3.3.4 Unidirectional Data Flow
  1. In React, there is a principle of one-way data flow, from top to bottom, from parent to child.

  2. The one-way data flow feature requires that our shared data be placed in upper-layer components.

  3. The child component changes the data by calling methods passed by the parent component.

  4. React rerenders the component tree when the data changes.

  5. One-way data flow makes the flow of data between components predictable. Makes it easy to locate program errors.

3.4 Class Component Status State

3.4.1 Defining component states

In addition to receiving state data from external props, a class component can have its own state, which can be updated within the component. The state update DOM updates.

The state data inside the component is stored in the state property of the component class. The value of the state property is the object type, and the property name is fixed and unchangeable.

Class App extends Component {constructor () {super() this.state = {person: {name: 'zhang ', age: 20 }, } } render () { return ( <div> {this.state.person.name} {this.state.person.age} </div> ); }}Copy the code
3.4.2 Changing component Status

The data in the state object cannot be changed directly. If you change the DOM directly, the DOM will not be updated. To change the state data, use the setState method.

Class App extends Component {constructor () {constructor () {this.state = {person: {name: 'zhang3 ', age: 2},} this.changePerson = this.changeperson.bind (this)} changePerson () {this.setState({person: {name: ' ', age: 15 } }) } render() { return ( <div> {this.state.person.name} {this.state.person.age} <button OnClick ={this.changeperson}> button </button> </div>); }}Copy the code
3.4.3 Bidirectional data binding

Two-way data binding means that the component class updates the state, the DOM state updates synchronously, the DOM changes the state, and the component class updates synchronously. Component <=> view.

To implement two-way data binding, you need form elements and state objects.

class App extends Component { constructor () { this.state = { name: } this.namechanged = this.namechanged. Bind (this)} nameChanged (event) {this.setState({name: event.target.value}); } render() { return ( <div> <div>{this.state.name}</div> <Person name={this.state.name} changed={this.nameChanged}/> </div> ) } }Copy the code
const Person = props => {
	return <input type="text" value={props.name} onChange={props.changed}/>;
}
Copy the code

Class 3.5 Component lifecycle functions

A snapshot is needed to do some kind of logic or calculation before a component can complete an update

componentDidUpdate(prevProps, prevState, snapshot) {}
Copy the code

The getSnapshotBeforeUpdate method is executed before the component has finished updating and is used to perform some kind of logic or calculation. The return value is retrieved from the third parameter in the componentDidUpdate method, meaning it can be retrieved before doing something else after the component has been updated.

getSnapshotBeforeUpdate(prevProps, prevState) {
  return 'snapshot'
}
Copy the code

3.6 the Context

Context allows you to pass data across hierarchies

// userContext.js
import React from "react"

const userContext = React.createContext("default value")
const UserProvider = userContext.Provider
const UserConsumer = userContext.Consumer

export { UserProvider, UserConsumer }
Copy the code
// App.js
import { UserProvider } from "./userContext"
class App extends Component {
  render() {
    return (
      <UserProvider value="Hello React Context">
        <A />
      </UserProvider>
    )
  }
}
Copy the code
// C.js
import { UserConsumer } from "./userContext"

export class C extends Component {
  render() {
    return (
      <div>
        <UserConsumer>
          {username => {
            return <div>{username}</div>
          }}
        </UserConsumer>
      </div>
    )
  }
}
Copy the code

Another use of context

// userContext.js
export default userContext
Copy the code
// C.js
import userContext from "./userContext"

export class C extends Component {
  static contextType = userContext
  render() {
    return (
      <div>
        {this.context}
      </div>
    )
  }
}
Copy the code

4. The form

4.1 Controlled Forms

The values in the form control are managed by the component’s State object, which stores values that synchronize state with the values in the form control

class App extends Component {
  constructor () {
    this.state = { username: "" }
    this.nameChanged = this.nameChanged.bind(this)
  }
  
  nameChanged (e) {
    this.setState({username: e.target.value})
  }
  render() {
    return (
      <form>
        <p>{this.state.username}</p>
        <input type="text" value={this.state.username} onChange={this.nameChanged}/>
      </form>
    )
  }
}
Copy the code

4.2 Uncontrolled forms

The value of a form element is managed by the DOM element itself.

class App extends Component {
  constructor () {
    this.onSubmit = this.onSubmit.bind(this)
  }
  onSubmit(e) {
    console.log(this.username.value)
    e.preventDefault();
  }
  render(
    <form onSubmit={this.onSubmit}>
      <input type="text" ref={username => this.username = username}/>
    </form>
  )
}
Copy the code

5. The routing

Mapping between URLS and components. Different urls are displayed for different components.

NPM install react-router-dom

5.1.1 Using Basic Routes

// App.js import React from 'react'; import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; Function Index() {return <div> </div>; } function News() {return <div> News </div>; } function App() {return (<Router> <div> <Link to="/index"> home </Link> <Link to="/news"> news </Link> </div> <div> <Route path="/index" component={Index}/> <Route path="/news" component={News}/> </div> </Router> ); }Copy the code

5.1.2 Route Nesting

Function News(props) {return (<div> <div> <Link to={' ${props.match.url}/company '}> Company News </Link> <Link To = {` ${props. Match. Url} / industry `} > industry news < / Link > < / div > < div > < the Route path = {` ${props. Match. The path} / company `} component={CompanyNews} /> <Route path={`${props.match.path}/industry`} component={IndustryNews}/> </div> </div> ); } function CompanyNews() {return <div> IndustryNews() {return <div> IndustryNews </div>}Copy the code

5.1.3 Route Parameter Transmission

import url from 'url'; class News extends Component { constructor(props) { super(props); This. state = {list: [{id: 1, title: 'new1'}, {id: 2, title: 'new1'}, this. }} render() {return (<div> <div> <ul> this.state.list.map((item, index) => { return ( <li key={index}> <Link to={`/detail? id=${item.id}`}>{item.title}</Link> </li> ); }) </ul> </div> ); } } class Detail extends Component { constructor(props) { super(props); } const { query } = url.parse(this.props.location.search, true); console.log(query); // {id: 1} render() {return <div> </div>}}Copy the code

5.1.4 Route Redirection

import { Redirect } from 'react-router-dom';

class Login extends Component {
  render() {
    if (this.state.isLogin) {
      return <Redirect to="/"/>
    }
  }
}
Copy the code