[react family bucket learning] component definition and state attribute in react (super detailed/must see)

Definition and characteristics of functional components

Definition (the core is a function that returns virtual dom):

import React from 'react'

export default function index() {
  return <div>index</div>
}

Features:

  • 1. Applicable to the definition of [simple components]
  • 2. It is a function that returns virtual dom
  • 3. The function name is the component name

Definition and characteristics of class components

Before learning, you can review the class-related knowledge:

ES6--class class (detailed / will read after reading)_class es6_suoh's Blog's Blog-CSDN Blog

Or review the knowledge points of the class to be used through the following code (read carefully, it is helpful):

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>

<body>
	<script>
		/**
		 * 总结:
		 * 1、类中的构造器不是必须写的,要对实例进行一些初始化的操作,如添加指定属性时才写
		 * 2、如果A类继承了B类,且A类中写了构造器,那么A类构造器中的super是必须要调用的
		 * 3、类中所定义的方法,都是放在了类的原型对象上,供实例使用
		 */
		// 创建一个Person类
		class Person {
			// 构造器方法,接收参数
			constructor(name, age) {
				// 构造器中的this是谁?---是类的实例对象(p1/p2)
				this.name = name
				this.age = age
			}
			// 一般方法
			speak() {
				// speak方法放在了哪里?--Person的原型对象上,供实例使用
				// 通过Person实例(p1/p2)调用speak时,speak中的this就是Person实例
				console.log(`我的名字是${this.name},我的年龄是${this.age}~`)
			}
		}
		// 创建一个Person的实例对象
		const p1 = new Person("小锁", 19)
		const p2 = new Person("小索", 20)
		p1.speak() //实例p1调用Person类原型链上的方法speak
		p2.speak() //实例p2调用Person类原型链上的方法speak
		p1.speak.call({
			a: 1,
			b: 2
		}) //使用call调用改变this指向,传的是谁,this就指向谁
		// 创建一个Student类,继承于Person类
		class Student extends Person {
			// 这里不需要接收s1传过来的姓名和年龄参数,因为我们继承了Person,
			// Person里面接收了这两个参数,下面我们只需要接收年级就好了
			constructor(name, age, grade) {
				// 下面写法不可取,因为属性多的时候,会和父类的赋值重复非常冗余
				// 	this.name = name
				// 	this.age = age
				// 因此我们利用super关键字,帮助我们在子类中调用父类
				// 将父类接收的2个参数传递过去即可
				// 注意:super关键字必须写在最前面,不能处于this.grade = grade之后
				super(name, age)
				this.grade = grade
			}
			// 重写从父类继承过来的方法
			speak() {
				console.log(`我的名字是${this.name},我的年龄是${this.age},我的年级是${this.grade}~`)
			}
			// 一般方法
			study() {
				// study方法放在了哪里?--类的原型对象上,供实例使用
				// 通过Student实例s1调用speak时,speak中的this就是Student实例
				console.log(`我的名字是${this.name},我的年龄是${this.age}~`)
			}
		}
		const s1 = new Student('小美', 19, '大学')
		console.log(s1)
		// 如果自身不存在学生也能访问到父类的speak方法,原型链的原因
		s1.speak()
	</script>
</body>

</html>l

Features:

  • 1. Applicable to the definition of [complex components]
  • 2. The component is defined by a class, and then an instance of the class is newly created, and the render method on the prototype is called through the instance
  • 3. Convert the virtual dom returned by render to real dom and present it on the page

Defined by:

import React, { Component } from 'react'
// 创建类式组件
export default class index extends Component {
  // render是放在哪里的?--在index组件的原型对象上,供实例使用
  // render的this是谁?--在index组件的实例对象(index组件实例对象)
  render() {
    console.log(this)
    return <div>index</div>
  }
}

Let's print this, and the output is the instance object of the component.

Supplement 1: What is a complex component?

Complex components: components with state are called complex components 

In addition to using external data (accessed via this.props), components can also maintain their internal state data (accessed via this.state) . When the state data of the component changes, the component will call the render() method again to recolor the corresponding markup. 

Supplement 2: What is state (state)?

  • state is the most important attribute of the component object, and the value is an object (can contain multiple key-value combinations)
  • Components are called "state machines" to update the corresponding page display by updating the state of the component (re-dyeing the component)
  • In react, just update the state of the component, and then re-render the user interface according to the new state (do not manipulate the DOM).

The value in the state can be modified, and the only way to modify it is to call  this.setState (described later) . After each modification, the this.render method is automatically called to render the component again.

(That is to say, this.state.num = 2it is invalid to modify the value directly in this way)
The state is assigned in the constructor of the component 

For example, let the page change according to the value in the state.

If we want to put a week parameter into state, note: the value of state is an object (can contain multiple key-value combinations), the steps are as follows

 It can be seen that the incoming is successful

 To read the value of state, just directly this.state.xxx

You can also use destructuring assignment to simplify the code

  

  

 Then we want to dynamically change this property through the click event, how to deal with it? Let's talk about event binding in react

Supplement 3: Event binding in react

The event binding in react is similar to native js, but with a little difference on the native basis,

For example, event naming methods: native onclick --> react is onClick, native onblur --> react is onBlur, etc.

  • React events are named in small camel case, such as (onClick) instead of pure lowercase (onclick)
  • When using JSX syntax, you need to pass in a function as an event handler instead of a string

try it:

The page reported an error. It seems that using a string is really not enough. 

 Translated, it is said that onClick must be a function instead of a string

 All right. Quite eventful, it seems that it has to be wrapped in curly braces to ensure that it is a function

Method 1: The click event is written in the render

 Note: If parentheses are directly added to the function of the label, then it will start calling as soon as it comes up.

So you need to remove the parentheses, so it's perfect~

 At this time, someone may find that the definition of my function testFunc above is located in render.

Method 2: Of course, there is another way of writing, which is to write the function outside (recommended). The difference between the two is as follows

Supplement 4: The difference between the react event function written inside and outside the render 

 React's event functions can be written in and out of render, but the difference between them is:

  • 1. The event functions written in render can be re-instantiated every time following the rendering cycle , which can ensure their latest state; while the event functions written outside render are only instantiated when they are loaded for the first time , and the latest state cannot be guaranteed .
  • 2. Event functions written in render can be re-instantiated to ensure that they have the latest props and state ; while event functions written outside render can only obtain their props and state when they are loaded for the first time , which cannot be guaranteed The latest props and state.
  • 3. The event function written in render can be combined with the content of render to achieve better readability and maintainability ; while the event function written outside render can make the code structure clearer and make the code easier to read .
  • 4. The event function written in render needs to add function, and this needs to be added when calling ; the event function written outside render does not need to add function, and it does not need to add this when calling .
  • 5. Calling this.setState event in render will fall into an infinite loop (the reason is refer to the blogger: Do not call this.setState_render in render to write setstate_Mr. Xiao Liu's blog-CSDN blog ) . Therefore, we still recommend writing outside render in most scenarios .

In short, the event functions written in render and outside render have their own advantages and disadvantages, and they should be selected according to the actual situation when using them.

Here comes the problem, now we can realize the click event, then I want to change the week value in the state when I click, how to write it? Some people say that it is better to assign directly.

 Look at the effect: when I clicked, an error was reported, saying that the state was undefined, which means that the state was not found through this.

Bold speculation: there is a problem with this pointing.

Supplement 5: How to modify the this point of the method in the class

 The this of the constructor and this in the render both point to the index component instance, so why is undefined appearing in the this of the function?

(1) Because the methods defined in the class have already enabled the strict mode locally ,

(2) It will be normal only if it is called through an instance, and testFunc is used as the callback of onClick , so it is not called through an instance, but is called directly, so this points to undefined

So next we can only change this to point to the index component instance, how to solve it?

The way to change the point of this is apply call  arrow function  bind, try them all

Both call and apply have been tried, and they are executed as soon as they come up, so it is not feasible

 

 Note: bind is to return the corresponding function, which is convenient to call later; apply and call are to call immediately.

            There are also arrow functions, which will be explained later in the article when the code is simplified

So we have to use bind

The key point is this sentence: this.testFunc = this.testFunc.bind(this) means to change the this point of the testFunc function on the prototype through bind (make it point to the index component instance) and return a new function to reassign to testFunc function, so that the this point of the testFunc function is normal,

 At this point, the normal this information is printed out.

 

 Supplement 6: How to change the value of the data in the state through this?

After solving the this point, we will not report an error when we access the state value in the method again.

 

Is the state value modified successfully? But why hasn't the page changed? ? ?

Note: You cannot directly modify the data in the state (this.state.week = 'Tuesday' [wrong wording]). To modify with the help of the built-in API [ setState ]

That's normal, 

 

Supplement 7: How many times does contructor call? How many times does render call?

AnswerConstructor is called only once, and render will be called 1+n times (1 is the initialization time, n is the number of state updates)

Small summary:

1. The role of the constructor

  • initialization status
  • Solve the problem of this pointing to the class method

2. The role of render

  • Read data from the state state
  • Display pages according to status

Code simplification one:

As mentioned in the review about classes above, the function of the constructor is mainly to receive the parameters passed in from the outside . When we don't need to receive the value passed in from the outside, we don't need the constructor . And you need to pay attention: you can directly write assignment statements in the class , but you can’t write code at will. The class is always not a function body. Variables, printing, etc. can be defined in the function body, which are not allowed in the class.

Therefore, we can put the state assignment statement in the constructor into the class, which means adding an attribute state to the instance object index

Code simplification two: 

When there are too many functions, we may write multiple statements in the constructor to change the point of this, which is very redundant

 Another way to change the point of this is the arrow function,,,,

 In this way, the constructor can be deleted, and after simplification

import React, { Component } from 'react'
// 创建类式组件
export default class index extends Component {
  // 初始化状态
  state = {
    week: '周一',
  }
  render() {
    const { week } = this.state
    return <h2 onClick={this.testFunc}>今天才{week}!</h2>
  }
  // 自定义方法--要用赋值语句的形式+箭头函数
  testFunc = () => {
    this.setState({
      week: '周二',
    })
  }
}

Finally, this is an explanation of a series of problems caused by changing the data on the react component page. I hope you can read it carefully, it will definitely help~

Guess you like

Origin blog.csdn.net/qq_41579104/article/details/130345358