Use variables in attributes

The basic use

this.state = {
    imgUrl: 'http://p1.music.126.net/uFtGUm56jgbGlBQOk_PGcw==/109951164832828416.jpg'
}

render(){{/* JSX is mainly written in the render function, and the React interface structure is then left to render */}
    const { imgUrl } = this.state

    return (
        <div>{/* You can use the curly braces syntax directly to use variables in attributes */}<img src={ imgUrl } alt="Network pictures" />
        </div>)}Copy the code

An image already appears on the screen

However, the image may be large, so we can resize the image in the following ways

  1. Use CSS to set it

    • Browsers parse THE CSS code
    • The browser needs to zoom the image

    Therefore, this setting is not recommended

  2. When retrieving the image URL, pass parameters to make it easier to retrieve images of different sizes (recommended)

    For example,

    // Address of the original image
    http://p1.music.126.net/uFtGUm56jgbGlBQOk_PGcw==/109951164832828416.jpg
    
    // On request, tell the server how high and how wide the image needs to be
    Request mode 1 -- Query string (NetEase Cloud)
    http://p1.music.126.net/uFtGUm56jgbGlBQOk_PGcw==/109951164832828416.jpg?param=140x140
    
    // Request mode 2 -- params parameter (simple book)
    https://upload.jianshu.io/users/upload_avatars/9838715/bb84ff12-e1b8-4226-93ba-5271229c29c0.jpg?imageMogr2/auto-orient/strip|i mageView2/1/w/240/h/240
    Copy the code
    • In this way, there is no need to deal with the size of the image on the browser side
    • Can increase the pressure on the server to process images

Call a function

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            imgUrl: 'http://p1.music.126.net/uFtGUm56jgbGlBQOk_PGcw==/109951164832828416.jpg'}}formatImg(url, w, h) {
        return `${url}? param=${w}x${h}`
    }

    render() {
        const { imgUrl } = this.state

        return (
            <div>{/ * can call a function expression in properties directly here to realize the image address formatting This operation is similar to the filter Vue imgUrl | formatImg * /}<img src={ this.formatImg(imgUrl.140.140) } />
            </div>)}}Copy the code

Some special names

{/* JSX mixes JAVASCRIPT and HTML together, but some HTML attributes have the same name as some JS attributes. In this case, the HTML attributes need to use JSX alias. For --> htmlFor= ==> such as  class --> className */}

{/* If no alias is used, no error will be reported, but warning */ will be reported}
<div className="box title"> I am a piece of text </div>Copy the code

Binding of styles

  1. Dynamically bind the class style
class App extends React.Component{
    constructor() {
        super(a)this.state = {
            active: true}}render() {
        const { active } = this.state

        return (
            <div>{/* 1. The dynamic binding style can use string concatenation 2. Because styles are separated by Spaces, you need to add a space after title (★★★) */}<div className={ 'box title'+ (active ? 'active' :"')} >A test text</div>
            </div>)}}Copy the code
  1. Dynamically bind style styles
class App extends React.Component{
    constructor() {
        super(a)this.state = {
            active: true}}render() {
        const { active } = this.state

        return (
            <div>{/* 1. There are two curly braces and parentheses to indicate that the JSX syntax needs to be used internally. Font size --> fontSize or 'font size' : '18px' Note that 'font-size' needs to be enclosed in single quotation marks to indicate a string of 4. Attribute values in the style object need to be passed to interpret string type data */}<div style={ { color: 'red', 'fontSize': '18px'}} >A test text</div>
            </div>)}}Copy the code

React event binding

The basic use

class App extends React.Component{
    constructor() {
        super(a)this.state = {
        }
    }

    render() {
        return (
            <div>{/* 1. Native JS events are all lowercase, but JSX events are written with a small hump. React encapsulates native JS events. The event passed in {} requires this to indicate that the current instance of this */} is called.<button onClick={ this.handleClick} >button</button>
            </div>)}handleClick() {
        console.log('I got clicked.')}}Copy the code

The this point in the event

Exposed problems

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '}}render() {
        return (
            <div>{/* 1. The React event will be called this.handclick.call (undefined) when calling the callback we passed in.<button onClick={ this.handleClick} >button</button>
</div>)}handleClick(){{/* 1. The value of this is undefined */}
    console.log(this.state.message)
}
}
Copy the code

Solution 1 —Use the bind method (implicit call)

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '}}render() {
        return (
            <div>{/* Bind will return a new function that changed this so this is changed back to the instance */}<button onClick={ this.handleClick.bind(this) }>button</button>
            </div>)}handleClick() {
        console.log(this.state.message)
    }
}
Copy the code

Remaining issues

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '}}render() {
        return (
            <div>{/* If there are multiple elements that need to be set to click events, there will be a lot of repeated bind operations, the code is very redundant */}<button onClick={ this.handleClick.bind(this) }>Button 1</button>
                <button onClick={ this.handleClick.bind(this) }>Button 2</button>
                <button onClick={ this.handleClick.bind(this) }>Button 3</button>
                <button onClick={ this.handleClick.bind(this) }>Button 4</button>
                <button onClick={ this.handleClick.bind(this) }>Button 5</button>
                <button onClick={ this.handleClick.bind(this) }>Button (6)</button>
            </div>)}handleClick(){{/* 1. The value of this is undefined */}
        console.log(this.state.message)
    }
}
Copy the code

Modified as follows:

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '
        }

        // When initializing the instance, change this from the instance
        // There is no need to repeat the bind part of the code
        this.handleClick = this.handleClick.bind(this)}render() {
        return (
            <div>{/* If there are multiple elements that need to be set to click events, there will be a lot of repeated bind operations, which is very redundant and reduces performance */}<button onClick={ this.handleClick} >Button 1</button>
                <button onClick={ this.handleClick} >Button 2</button>
                <button onClick={ this.handleClick} >Button 3</button>
                <button onClick={ this.handleClick} >Button 4</button>
                <button onClick={ this.handleClick} >Button 5</button>
                <button onClick={ this.handleClick} >Button (6)</button>
            </div>)}handleClick() {
        console.log(this.state.message)
    }
}
Copy the code

Method 1 although React this points to the component instance object

But if you click, you need to pass a different parameter to handleClick

There is no way to modify this reference uniformly in constructor

Therefore, this method is not recommended

Solution 2 —Using the arrow function

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '}}render() {
        return (
            <div>
                <button onClick={ this.handleClick} >button</button>
            </div>
        )
    }

    handleClick = () = >{{/* The arrow function does not have this inside it, so according to the js scope chain, the this inside the arrow function will be searched one level up until the global scope is found. In ES6, if you want to use arrow functions to define methods, you can only use class fields to define methods. However, this definition is essentially a member property, not a method, so it still needs to be modified */}
        console.log(this.state.message)
    }
}
Copy the code

Method 3 – Pass the arrow function when the event listens

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            message: 'React event this points to the problem '}}render() {
        return (
            <div>{/* Wrap a layer of arrow functions around the function call. Since there is no this inside the arrow function, it is meaningless to bind this to the arrow function. Because of the scope chain, the this of the handleClick call is the outer this of the current component object.<button onClick={() = >Enclosing handleClick} > button</button>
            </div>)}handleClick() {
        console.log(this.state.message)
    }
}
Copy the code

Method 3 is used to modify this. The callback defined is a function, not a member variable in method 2, and it is easier to pass parameters.

Therefore, method 3 is recommended

React calls and passes parameters

3.1 Event Invocation

Native event invocation

<div id="dv">Click on the I</div>

<script>
    document.getElementById('dv').addEventListener('click'.e= > console.log(e))
</script>
Copy the code

React calls to events

class App extends React.Component{
    constructor() {
        super()}btnClick(e) {
        console.log(e)
    }

    render() {
        return (
            <div onClick={e= >This.btnclick (e)}> {/* 1. React events encapsulate native JS browser events with a default event that is a collection of all browser attributes associated with the current event. When you call the React event function, it also passes in an event object. This event object is a secondary encapsulation of the native browser event object. React calls an external arrow function, so its default event object is passed to the arrow function, so you need to manually pass it to the object that is actually called internally. 3. The advantages of using the arrow function wrapper to actually call the function are: 1. The internal THI points to the instance object ---- React. 2. Function calls are made by themselves, not by react, so for better control of passing arguments and using them, click me</div>)}}Copy the code

Native event objects

React event object

3,2 parameter passing

Requirements:

There is a list. Click on the list item and print the element name, index value, and this object in the console

Use bind to make the call

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            persons: [
                'Jonathan'.'Li Sisi'.'Net nothing nothing'.'Lily Liu']}}liClick(item, index, e) {
        console.log(item, index, e)
    }

    render() {
        const { persons } = this.state

        return (
            <ul>
                {
                    persons.map((item, index) => {
                        return (
                            <li onClick={this.liClick.bind(this, item.index)} >{/* If bind is called, You can pass an argument after bind but it cannot be written in a constructor such as this.liclick = this.liclick. Bind (this, item, When liClick is called, it still passes an event object, but the event object is not the first argument. LiClick (item, index, e) (★★★) */} {item}</li>)})}</ul>)}}Copy the code

Use the arrow function to make the call

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            persons: [
                'Jonathan'.'Li Sisi'.'Net nothing nothing'.'Lily Liu']}}liClick(item, index, e) {
        console.log(item, index, e)
    }

    render(){{/* Object destruct */}
        const { persons } = this.state

        return (
            <ul>
                {
                    persons.map((item, index) => {
                        return (
                            <li onClick={e= >This. LiClick (item, index, e)}> {/* pass event parameters */} {item}</li>)})}</ul>)}}Copy the code

Fourth, conditional rendering

Requirement: Welcome back will be displayed on the page when the user logs in. If the user does not log in, please log in first will be displayed

If expression

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            isLogin: false}}render(){{/* Each time the render function is called, the function execution context is reopened, and a new constant */ is created in it}
        const { isLogin } = this.state
		
        let msg = null

        if (isLogin) {
            msg = <h2>Welcome back</h2>
        } else {
            msg = <h2>Please login first</h2>
        }

        return (
            <div>
                { msg }
            </div>)}}Copy the code

Ternary operator

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            isLogin: false}}render() {
        const { isLogin } = this.state


        return (
            <div>
                <h2>{ isLogin ? 'Welcome back' : 'Please log in first '}</h2>
            </div>)}}Copy the code

Use logic and operators

Requirement: If the user’s name is displayed on the interface after login,

If the user is not logged in, nothing is displayed

<div>
    {/* If isLogin is true, return the value of userName. If isLogin is false, return false. If isLogin is false, the page contains an empty 

*/
} <h2>{ isLogin && userName } </h2> {/* There is no empty H2 tag */ if isLogin is false when writing this way} { isLogin && <h2>userName</h2> } </div> Copy the code

4.1 Simulate V-IF and V-show

There are two common directives that control the display and hiding of elements in vUE

V-if controls the display and hiding of elements by removing and adding elements is suitable for elements with low switching frequency

V-show controls the display and hiding of elements by setting the display attribute of elements. It is suitable for elements with high switching frequency

Simulation of v - the if

class App extends React.Component{
    constructor() {
        super(a)this.state = {
          isLogin: false.userName: 'Klaus'}}render() {
        const { isLogin, userName } = this.state


        return (
            <div>
                <h2>{ isLogin && userName } </h2>
            </div>)}}Copy the code

Simulation of v - show

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            isLogin: false.userName: 'Klaus'}}render() {
        const { isLogin, userName } = this.state


        return (
            <div>
                <h2 style={{'display' : isLogin ? 'block': 'none'}} >{ userName } </h2>
            </div>)}}Copy the code

5. List rendering

5.1 Simple list rendering

class App extends React.Component{
    constructor() {
        super(a)this.state = {
            nums: [15.20.43.54.76.123]}}render() {
        const { nums } = this.state


        return (
            <ul>
                {
                    nums.map(item => <li>{ item }</li>)}</ul>)}}Copy the code

5.2 Display data items greater than 50

<ul>
    {
        nums
            .filter(item= > item > 50)
            .map(item= > <li>{ item }</li>)
                 }
</ul>
Copy the code

5.3 Displaying the first four data items

<ul>
    {
        nums
            .slice(0.4)
            .map(item= > <li>{ item }</li>)
                 }
</ul>
Copy the code

supplement

  1. Basically, most HTML tags have a title attribute, which represents a message when the mouse is hovering over it

    <div title="This is a div"></div>
    
    <img src="Here's the address of the picture." alt="This is the alternative text when the image fails to load."  title="This is the text when the mouse hovers over it." />
    Copy the code
  2. The map and filter methods of a numeric value have two parameters, namely callback, and the this reference when the function is called. Each callback has three parameters, namely item, index, arr,

Arr. Map ((item, index, arr) => return item, this points to) Arr. Filter ((item, index, arr) => return Boolean, this points to)Copy the code
  1. An array ofsliceThe () method intercepts an array and returns it
'arr. Slice (start, end) ==> return 'start' must be a positive integer greater than 0. 'end' can be a negative integer. '-1 ==> -1 + arr. Length ==> is the last element of the array. So the default value of the second argument is' arr.length ', which means that the elements of the array start at the beginning and end at the end of the array (' arr.length -1 ', So ` contains `) for example, the last element [1, 2, 3, 4, 5]. Slice (2) = = > [3, 4, 5]Copy the code

React Learn Notes – JSX core syntax (1