Preface:
As for why I want to write this article, on the one hand, I was inspired to read an article named “You know how to use ES6, then you should use it” a few days ago. Most of the things I said in the article are really experienced by me. Obviously I have learned some knowledge and skills, but I always can’t remember to use them in my work. On the other hand is the most recent resignation at home finishing your resume and what they have done over the past two years, so I want to share my personal feelings about my opinion of improving the quality of the code and practice, mainly from the Angle of conventional methods and recommended to obtain, analyze how to make our code looks more elegant, run up more excellent performance. The article is quite long, it is suggested to collect it slowly.
Note: the article about some knowledge points shared before, there are links to support, can reuse here will not repeat, because I do not want to make up the number of words and write, this is not my original intention. I share what I think is good to everyone, but also in this process to consolidate their knowledge of the knowledge, I hope this virtuous cycle will continue.
Code quality is a broad topic, and I’ll share it from three aspects (to be added later) :
1. Code refactoring;
2. ES6 (7, 8, 9, 10);
3. React optimization.
I. Code refactoring
Refactoring is probably one of the things people don’t want to do because it means reworking the code logic, the functional requirements, and the potential for delays. But I am feeling is we need to have a sense of incremental refactoring exist, if the current code has been far behind the existing technology, has been unable to tolerate or readability, so what are you waiting for, the best solution is to reconstruct, reconstruction can greatly improve the readability of the code, increasing the simplicity of the code, and more convenient maintenance.
1. Resource coordination before reconstruction
When we want to reconstruct, the first thing to consider is to make the business side aware of the necessity of the reconstruction, consult the remaining resources of each department, and persuade each department to participate in the front-end reconstruction.
Reasons for refactoring: frequent changes in requirements, urgent requirements reversal, simultaneous development without long-term planning direction, team code style differences, technology updates and iterations, etc.
The need for refactoring: Emphasized reconstruction technology of benefits and business benefits, provide the feasible reconstruction plan (including human resources, scheduling, scope changes, etc.), business letter, products, and the back-end, test, see the pain points and technical bottlenecks in the development, such as of the consequences that may not refactoring (update the limitations of iteration, the development progress of slow, troubleshoot problems difficult)
Benefits of refactoring: fewer bugs, lower maintenance costs, faster troubleshooting, faster development, etc
2. Refactoring steps
According to the scope involved in reconstruction, it can be divided into the following four scenarios:
A. Facelift (vue -> react
);
As soon as I joined my second company, I took part in a big reconstruction, replacing the original old project vUE with React. We first set up the framework, and then made a prioritization of the various pages that need to be reconstructed. Design, front end, back end and testing were all involved. Most of the interfaces could still be reused, but the front end needed to be rewritten. The point here is to make sure old projects work, and that new features are tweaked as much as possible in new projects, prioritized, and migrated over time.
B. Normative reconstruction of code format (js -> ts
);
The key point of this reconstruction is: first choose a target or a change direction, make sure that every change can run, after all, static check is not the function logic of the change itself, the probability of error is small, we can modify a small number of times.
C. Reconstruction of common components;
About the reconstruction of public components, should follow the principle of graceful degradation and progressive enhancement, if the current common components are dependent on less, the one-time can complete all update, but if it is using the high frequency component reconstruction may affect the broader extension, that need to be compatible with the old way do incremental updating reconstruction at the same time, the subsequent will gradually give up the old method during the revision.
D. Reconstruct specific functions.
Originally thought that text can express clearly, but when I write down, I find that drawing is more clear:
First check whether there are references by other components and dependencies. If there are, ensure that this reconstruction will not affect them. If there are no, sort out the current business, and synchronize the modification scope with the test and product (generally, if there are no back-end changes involved, notify the backend. In case of any problems, we need to consult the backend students) -> front-end development -> collaborative test to complete regression -> notify product acceptance -> notify the business side of changes, establish a wechat issue group of the enterprise, and ensure that there is any problem feedback at any time
3. Code modification rules
For code modification, you are advised to follow the following rules:
- Single responsibility principle
(SRP: Single responsibility principle)
Also known as the single function principle, object – oriented five basic principles (SOLID). It states that a class should have only one reason for change.
Name: Single responsibility principle
Single Responsibility Principle
There should never be more than one reason for a class to change. There should be one and only one reason for a class to change… It means that no matter what I do, I only do one thing. If you tell me to go grocery shopping, I only do grocery shopping. If you tell me to take out the garbage, I don’t do it
Temper: a word “ye”, two words “especially ye”
Partner: I have a single responsibility. Where can I find my partner?
Personal introduction: In this multi-responsibility society, I seem to be so maverick, but I do not know that a lot of things happening in the society are caused by the failure to deal with responsibilities, for example, often some parents with their children, while playing mobile phones, resulting in lost children, accidents and so on
In fact, it means that a method, a page component is best only one function or responsibility, as little as possible to coupling multiple functions in the same method, so for the later to find problems, reuse logic is a good habit.
Excerpt from Digger friend: LieBrother
- Naming conventions
Naming conventions are commonplace, we often make fun of other people’s naming rules at the same time, we also need to pay attention to their own naming rules, like your wardrobe clothes, at a glance to be more uniform. Naming rule reference
- The style is unified
Uniform code style, each of us has his or her own style of development, but in many cases, the code written by the same person will have multiple styles, which leads to the later maintenance of the code written by oneself is not easy to find problems. If the company team has norms, we try to comply with, or you think the company’s norms are not right, you can put forward, and then the team development as close as possible to it, so that we do not have too many complaints later maintenance, haha….
- Duplicate code —
Repeat Code
With regard to duplicate code I recommend that if there are more than one feature component at the page level, if there are more than three references to common components. We try to minimize repetitive code writing, which on the one hand wastes time and on the other hand is difficult to maintain. Of course, functional components and common components can also be differentiated and return different contents according to different parameters.
The last:
A final thought: When code smells bad, the first thing we do is flag it and schedule time to improve it. For example, you find that someone dug a hole in the wall you pass every day. After two days, you find that the hole is getting bigger and bigger, probably because you can take a shortcut through it. However, when more people walk, the hole is getting bigger and bigger, and the wall is becoming more and more dangerous, and there may be a landslide at any time. When we see this hole, can we think about it: since this shortcut brings convenience to everyone, can we inform the property management or neighborhood committee to remove this wall? If it’s a code problem, can’t be removed, or how to repair the wall? Instead of watching it get more dangerous every day. You know, no snowflake in an avalanche is innocent.
Second, the ES6
ES6 here is a broad concept, including but not limited to ES6, ES7, ES8, ES9, ES10, an overall concept. Today, I will share with you some common ES6 usage habits in my daily work. If there is any mistake, please correct me.
1. Variable definition:
The first is the definition of variables. Var is no longer used in the code. Instead, let and const are used, and most of them are const because of their differences 👇.
Let const var
-
Let const is block-level scoped. Variables only apply to declared code blocks. Var does not.
-
The var variable declaration is promoted to the head of the code block, which violates the rule of using variables first;
-
Another reason is that the JS editor optimizes const to improve the efficiency of the program.
-
A const declaration of a constant has two additional benefits. One is that readers of the code immediately realize that the value should not be changed, and the other is that it prevents errors caused by unintentional changes to the value of a variable.
-
A const declaration must be assigned, only once. An object declared by const can change its properties;
-
The let variable can be declared once and then assigned multiple times
Conclusion: From var to let const, this habit is to change their perception. See here if you’re already doing this, you’re great. If your mind is still stuck in the var era, it’s time to do a bit of research, because it’s a habit you need to develop in order to make your code more rigorous.
2. Default parameters:foo(a=1,b=2)=>{}
A function that takes a line argument, provides an initial value when the argument is missing or the value is undefined, and then determines whether to enable the default value depending on the case.
Missing:
Const foo = (name='xiaoqiu', age = 18) => {console.log(name,age)} // Default parameter value foo('zhangsan') // zhangsan 18 is automatically enabled when missingCopy the code
undefined:
Const foo = (name='xiaoqiu', age = 18) => {console.log(name,age)} // When the second parameter is undefined, it is identified as unassigned, The default parameter foo('zhangsan',undefined) // zhangsan 18 is automatically enabledCopy the code
null / fasle:
Const foo = (name='xiaoqiu', age = 18) => {console.log(name,age)} Foo ('zhangsan', NULL) // zhangsan null foo('zhangsan',false) // zhangsan falseCopy the code
3. Template string
Updated the way we use strings. Before template strings, we wanted to concatenate variables in strings that required ‘string’ + variable + ‘string’ to assemble, which was neither pretty to look at nor cumbersome to write. When we have template strings, variable concatenation is easy, and it is possible to make strings perform computations and functions.
Variable stitching
const name = `xiaoming`; const age = 18 ; Console. log(' My name is ${name},${age}. // My name is xiaoming,18.Copy the code
Line joining together
const a = `123
456`;
console.log(a)
// 123
// 456
Copy the code
Perform calculations
const x=10;
const y=100;
console.log(`a=${x-5},b=${x+y}`); // x=5,y=110
Copy the code
Executive function
Function answer(){return "Today is Monday "; } console.log(' Me: What day is it today? ${answer()} '); Me: What day is today? // You: Just a moment, let me see. Today is MondayCopy the code
4. Deconstruct assignments
ES6 allows you to extract values from arrays and objects and assign values to variables in sequence according to a certain pattern. This is called deconstruction. The concept is abstract, and the following is illustrated with practical examples.
Union declarations with arrays:
const [a, b, c] = [1, 2, 3];
Copy the code
Array deconstruction:
const [x, y, z] = [1, 2, 3];
x // 1
y // 2
z // 3
Copy the code
Array deconstruction — assignment of remaining arguments:
const [x, y, ...z] = [1, 2, 3, 4, 5];
x // 1
y // 2
z // 3,4,5
Copy the code
Json data deconstruction:
const obj = { a: 'haha', b: 'gaga' ,c: 'guagua'};
const {a, b, c} =obj;
a // haha
b // gaga
c // guagua
Copy the code
Complex JSON data deconstruction:
let node = { type: "Identifier", name: "foo", obj: { start: { line: 1, column: 1 }, end: { line: 1, column: 4 } } }; Node.obj. start let {obj: {start: localStart}} = node; console.log(localStart.line); // 1 console.log(localStart.column); / / 1Copy the code
String deconstruction:
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
Copy the code
Function argument deconstruction:
function add([x, y]){ return x + y; } add([1, 2]); / / 3Copy the code
Destruct the return value of a function directly:
function example() {
return [1, 2, 3];
}
const [a, b, c] = example();
Copy the code
Swap variable values:
const a = 1;
const b = 2;
[a, b] = [b, a];
Copy the code
Module specified method destruct:
import { useRequest } from 'ahooks';
Copy the code
There are a lot of scenarios for deconstructing assignment. The above is just a list of my common ones. Welcome to add!
5. Arrow function
ES6 allows the use of “arrows” (=>) to define functions. Delete the function keyword and function name from the original function and use => to concatenate the argument list with the function body. It doesn’t have its own this, arguments, super or new.target.
Arrow functions are different from normal functions
- In vivo function
this
Object is the object at which you define it, not the object at which you use it. Arrow functions cannot be modified directlythis
Point; - Cannot be used as constructors, that is, not used
new
Command, otherwise an error will be reported; - Unusable
arguments
Object that does not exist in the function body. You can use it if you wantrest
Parameter substitution; - Unusable
yield
Command, so the arrow function cannot be usedGenerator
Functions; - Arrow functions do not support renaming function arguments.
The arrow function this points to:
- Ordinary functional
this
Object pointing is mutable, but in the arrow functionthis
Is fixed, the actual reason is that the arrow function doesn’t have its ownthis
Lead to internalthis
That’s the outer code blockthis
ï¼› - Arrow function
this
Refers to the parent scopethis
, is determined by looking at the scope chainthis
That is, it points to the object on which it is defined, not the object on which it is used; A normal function points to its direct caller; - The arrow function has no normal function outside, in strict mode and in non-strict mode
this
Leads towindow
Global object.
Writing style:
// const f = function (a) {return a; }; // arrow function const f = a => a; Const f = () => {return "1"}; // Const f = () => {return "1"};Copy the code
Use REST instead of arguments
const numbers = (... nums) => nums; numbers(1, 2, 3, 4, 5)Copy the code
6. Operator extension
Operators perform program code operations on more than one operand item. Here’s a rundown of the various es6 operators, the last one I haven’t used before: 🤔
Extended operators…
The spread operator is three points… , which is like the inverse of the REST argument, turns an array into a comma-separated sequence of arguments that can only be placed in the last bit of the argument when placed in an array.
Expand values, unbracket arrays, merge arrays, :
console.log(... [1, 2, 3]) // 1 2 3 console.log(1, ... [2, 3, 4], 5) // 1 2 3 4 5 console.log([ 1, ...[2, 3, 4], 5 ]) // [1, 2, 3, 4, 5]Copy the code
Merger Statement:
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(rest) // [2, 3, 4, 5]
Copy the code
Merge arrays/objects:
,4,7,9 const a = [2] / / ES5 [1, 2] concat (a) / / [1, 2, 2, 4, 7, 9] / / ES6 [1, 2,... a] / [1, 2, 2, 4, 7, 9]Copy the code
String extensions to arrays:
[...'happy']
// [ "h", "a", "p", "p", "y" ]
Copy the code
Expand the objects of the Iterator interface:
The extension operator internally calls the Iterator interface of the data structure, so it can be used by any object that has an Iterator interface.
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
[...map.keys()]; // [1, 2, 3]
[...map.values()]; // ['one', 'two', 'three']
Copy the code
Arrays and object copies:
You can also copy objects using extension operators, which we shared earlier, and here’s the portal
With the new Set array to deduplicate:
const arr = [1, 2, 1, 2, 6, 3, 5, 69, 66, 7, 2, 1, 4, 3, 6, 8, 9663, 8];
console.log([...new Set(arr)]); // [1, 2, 6, 3, 5, 69, 66, 7, 4, 8, 9663]
Copy the code
Optional chain? .
The optional chain operator (? .) allows you to read the value of a property located deep in the chain of connected objects without explicitly validating that each reference in the chain is valid. ? The. Operator functions like the. Chain operator, except that it does not cause errors when references are nullish (null or undefined), and the short-circuit returns undefined. ? The. Operator acts as a short-circuit mechanism that stops executing if the condition is not met.
When we have a variable message and we want to get the value of one of its nodes, the old way of doing this is to make sure that we don’t get an error, layer by layer
// ES5:
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
Copy the code
Now, what do you do, just use the chain call, check? Does the preceding content exist in the upper object of the property, whether it is null or undefined, return undefined if it does not exist, if it does exist, continue to call backwards, then message? .body is equivalent to message.body, simplifying writing.
// ES6: const firstName = message? .body? .user? .firstNameCopy the code
When used with a function call, returns undefined if the given function does not exist.
onCancel={() => { setVisible(false); onClosed? . (); }}Copy the code
Null-value merge operator??
Null-value merge operator (??) Is a logical operator that returns the right-hand operand if the left-hand operand is null or undefined, otherwise returns the left-hand operand.
const foo = null ?? 'default string'; console.log(foo); // "default string" const baz = 0 ?? 42. console.log(baz); / / 0Copy the code
Exclude non-null and undefined false values:
In this line of code, we want to use the default value of undefined/null on the right side, but in fact, if the left side of the input parameter is false, 0, ‘ ‘, it will return the default value of the right side, which is a bit contrary
ES5: const okText = props? .buttonProps? .loading || false;Copy the code
With the optional chain operator setting the default value, we can do what we need
ES6: const okText = props? .buttonProps? .loading ?? falseCopy the code
Logical operator
Es6 new logical operators | | =, && =?? =, these three operators are equivalent to performing the logical operation first, then performing the assignment based on the result of the operation, and then depending on the situation.
And (OR) logical operators | | =
Logical OR assignment (x | | = y) operator only in x is falsy value assignment.
const b = { a : 2 } ; / / b.a left back 2, not false, the results back 2 b.a | | = 4; console.log(b.a) ; / / 2 / / b.d prototype chain was not found on the left side of the b d, returns false, assign a value to the right, the result b.d assignment of 8 b.d | | = 8; console.log(b.d) ; // 8 b.c = 23 console.log(b) ; // {a: 2, d: 8, c: 23}Copy the code
Set default values for property values:
// ES5
user.age = user.age || 18;
// ES6
user.age ||= 18;
Copy the code
Logic (AND
The assignment operator &&=
The logical AND assignment (x &&= y) operator only assigns if x is true.
let a = 1; let b = 0; // the left side of the operator is true and returns 2 a &&= 2; console.log(a); // the operator is false on the left and does not assign b &&= 2; console.log(b); / / 0Copy the code
Logical null assignment?? =
The logical null assignment operator (x?? = y) only if x is nullish (null or undefined).
Did we just learn one above? And now this…? What’s the difference between lambda and this? The main difference is…? = is assignment,?? Just judge logic, above example 🌰 :
Const a = {b: 2, c: 0, d: false}; / / use?? To determine that the result is not assigned to a.e. A.E?? 99; console.log(a.e) ; // undefined // requires a separate declaration and assignment, so?? Const l = a.e?? 99 console.log(l) // =, the result is an a.f?? That can be added to the a object. = 100; console.log(a) ; // {b: 2, c: 0, d: false, f: 100} console.log(a) ; // {b: 2, c: 0, d: false, f: 100, ee: null} ;Copy the code
Assign an attribute value to a parameter:
// Old method: function example(params) {function example(params) {params? .loading = params? .loading ?? false (params? .okText) ?? Function example(params) {function example(params) {function example(params)? .loading ?? = false params? .okText ?? = 'confirm'}Copy the code
Exponentiation operator **
The exponentiation operator (**) returns the result of adding the first operand to the power of the second. It is equivalent to math.pow, except that it also accepts BigInts as its operand.
Math.pow(3,4) // 81 console.log(3 ** 4); // 81 console.log(10 ** -2); // 0.01 console.log(2 ** 3 ** 2); // 512 console.log((2 ** 3) ** 2); / / 64Copy the code
7. Extensions to array methods:
For the array operations, we can combine the previously shared array methods to see, next we will analyze the new array operations on ES6:
Array.of()
Creating an array instance
The array.of () method creates a new Array instance with a variable number of arguments, regardless of the number or type of arguments.
Array.of() and Array:
The difference is in the handling of integer arguments: array.of (7)**** creates an Array with a single element 7, while Array(7) creates an empty Array of length 7 (note: this is an Array with seven empty Spaces, not an Array with seven undefined).
Array.of(7) // [7]
new Array(7) // [empty × 7]
Copy the code
Array uncertainty
Array() // [] Array(3) // [empty × 3] Array(3, 11, 8) // [3, 11, 8]Copy the code
Determinism of array.of
/ / regardless of the number of parameters. The returned Array is an Array of () / / [] Array of (3) / / [3] Array) of (3, 11, 8) / / [8] 3, 11,Copy the code
To convert a set of values to an array:
Array. Of (1,2,3) // [1, 2,3] Array. Of (1,2,3) // [1, 2,3] Array.Copy the code
Includes determines whether an array contains a specified value
The includes() method is used to determine whether an array contains a specified value, returning true if it does and false otherwise. This method is very similar to the one we are familiar with, indexOf, but indexOf returns -1 instead of a Boolean value of true/false, which is a little less elegant in determining the result.
const array1 = [1, 2, 3];
console.log(array1.includes(2)); // true
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat')); // true
console.log(pets.includes('do')); // false
[1, 2, NaN].includes(NaN); // true
Copy the code
Array.from
Creating a new array
The array.from () method creates a new, shallow-copy Array instance from an array-like or iterable. This method was shared in the original Array method collation, linked here to array.from
find()
和 findIndex()
Finds the value of a compound condition on an array
The find() method returns the value of the first element in the array that satisfies the provided test function. Otherwise return [undefined]
Example find
The findIndex() method is similar to find in that it looks for the first element but returns the index of the first element in the array that satisfies the provided test function. Returns -1 if no corresponding element is found
const array1 = [5, 12, 8, 130, 44]; const isLargeNumber = (element) => element > 13; console.log(array1.findIndex(isLargeNumber)); / / 3Copy the code
fill()
Fill the array
The fill() method fills all elements of an array from the start index to the end index with a fixed value. Does not include terminating indexes.
You can accept up to 3 parameters: arr.fill(the value to be filled, the start of the fill, and the end of the fill)
const array1 = [1, 2, 3, 4]; Log (array1.fill(6)); console.log(array1.fill(6)); Log (array1.fill(5, 1)); Console. log(array1.fill(0, 2, 4)); console.log(array1.fill(0, 2, 4)); // [1, 2, 0, 0]Copy the code
copyWithin
Copy the array
The copyWithin() method shallowly copies part of the array to another location in the same array and returns it without changing the length of the array.
You can accept up to 3 arguments: arr.copywithin (the starting position of the replacement, the beginning position of the replacement, and the end position of the replacement in the old array)
const array1 = ['a', 'b', 'c', 'd', 'e'];
Copy the code
console.log(array1.copyWithin(0, 3, 4));
// ["d", "b", "c", "d", "e"]
Copy the code
👆 since the location of the index of 0 are covered, the index of 0 is’ a ‘, starting from the index position of the 3 assignment, index 3 position is’ d ‘, then the array is a ‘d’ 0, to the end of the index for 4 place, including index in front of the position, the final index does not include the location, that is the copy one, the rest of the default pad: [‘d’, “b”, “c”, “d”, “e”]
console.log(array1.copyWithin(1, 3));
// ["d", "d", "e", "d", "e"]
Copy the code
👆 this method changes the original array, at which point our copy of the original array becomes the return value above: [“d”, “b”, “c”, “d”, “e”]. [‘d’,’d’,’e’], “d”, “e”, “d”, “e”, “d”, “e”, “d”, “e”]
Conclusion: When I first came into contact with this method, I felt it was not easy to understand, thinking: Who would use such a difficult to understand the method to operate the array, re-declare an array is not very convenient, copy to copy is not enough trouble, so that the back will never use, today again look is also a reasonable next to remember, so write a lot of description, I hope to help you. As for the use of scenarios, you can use them in some word games, or in games such as pushing boxes, other scenarios are still to be explored, if you know of other scenarios, please leave a comment to me at 👇.
flat()
.flatMap()
Array flattening
The Flat () method recurses through the array of numbers at a specified depth and returns all the elements in a new array combined with the elements in the traversed subarray. Refer to the flat of the original array method
aboutES6
Void of array in:
The vacancy of an array
8. String extensions:
For other string methods, see here, but only the most recent ones in ES6
trimStart
和 trimEnd
Delete before and after whitespace, does not affect the original array
The trimStart() method removes whitespace from the beginning of the string. TrimLeft () is an alias for this method.
const greeting = ' Hello world! ';
console.log(greeting.trimStart()); // 'Hello world! ';
console.log(greeting.trimLeft()); // 'Hello world! '
Copy the code
The trimEnd() method removes whitespace characters from the end of a string. TrimRight () is an alias for this method.
const greeting = ' Hello world! '; console.log(greeting.trimEnd()); // " Hello world!" ; console.log(greeting.trimRight()); // " Hello world!" ;Copy the code
For more regular methods to remove whitespace, see here
PadStart and padEnd fill strings
The padStart() method populates the current string with another string (repeated multiple times if necessary) so that the resulting string reaches the given length. PadEnd () is used for tail completion.
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
Copy the code
9. Promise. All ([a, b]), execute multiple promises simultaneously
The promise.all () method is used to wrap multiple Promise instances into a new Promise instance. The Promise’s resolve callback is executed when all the incoming Promise’s resolve callbacks have ended, or when no promises are left in the input iterable. Its Reject callback execution throws an error as soon as any incoming promise’s Reject callback is executed or an invalid promise is entered, and reject is the first error message thrown.
const p = Promise.all([p1, p2, p3]);
Copy the code
The state of P is determined by P1, P2 and P3, which can be divided into two cases.
(1) Only when the states of P1, P2 and P3 become depressing, the state of P will become depressing. At this time, the return values of P1, P2 and P3 will form an array and be passed to the callback function of P.
(2) As long as p1, P2 and P3 are rejected, P becomes rejected, and the return value of the first rejected instance is passed to p’s callback function.
Promise.all([... formlist.map (item => item.validateFields())), validateFields()]).then(data => { ... dosomething });Copy the code
Third, the React
In this session, we’ll share some of the elegant writing styles and methods in the React framework, as well as the different uses of similar methods and performance improvements.
Note: HERE I assume you are already familiar withreact
Framework and understand its basic use, if not too familiar with, aboutreact
I published an article in the past,You can see here
Below I will use the form of question and answer to share, about inreact
How to better improve performance optimization and improve work efficiency.
About 1.vue
和 react
The discussion about VUE and React has always been the focus of public opinion. Although an unnamed bigwig said: The current situation is that generally large companies use React more, while small companies use VUE more, there is no absolute opinion on which is better, and it is all relative. My personal opinion is as follows: Whichever is comfortable to use is fine. Here are the obvious differences I feel.
Differences in writing styles:
Vue:
Vue recommends the single file component format of Webpack + VUe-Loader. Vue retains the separate writing method of HTML, CSS and JS, so that the existing front-end developers can keep their original habits when developing, which is closer to the common Web development mode. The template is ordinary HTML. Mustache is used for data binding and CSS is used directly for styling. The
react:
React is a rendering function that returns a virtual DOM tree. React recommends JSX + inline style, which translates HTML and CSS into JavaScript: ‘all in JS ‘. JSX is really a set of syntactic sugar that uses XML syntax to make it easier to describe tree structures. In React, all components rely on JSX for rendering. You can write xmL-like syntax in Render (), which will eventually be compiled into native JavaScript. Not only can HTML be expressed in JSX, but the trend is to incorporate CSS into JavaScript as well. JSX is a set of additional grammars based on JS that can be learned and used at a cost.
About data binding:
Vue:
It is known for two-way data binding, but also one-way data flow. Why? In fact, the two do not conflict. One-way data flow means that data flows in a single direction, that is, from the parent component to the child component. When the child component receives the data from the parent component, it cannot modify the data of the parent component.
Data flow:
Graph TD parent --> child component
What about two-way data binding? The key to bidirectional binding is how data updates the view, because a view updates data by listening for events, such as input tags listening for ‘input’ events. So let’s focus on how we update the view when the data changes. The focus of the data update view is how to know that the data has changed, and once you know that the data has changed, then everything else is easy to deal with. DefineProperty () sets a set function on the property. This function is triggered when the data changes, so we can update the view by putting in some methods that need to be updated.
react:
React is also a one-way data stream, but the data binding is one-way. Instead of changing state directly, use setState to change data. It doesn’t take effect immediately, it’s asynchronous. So don’t assume you can get the latest value immediately after calling setState. Sequential setStates are not executed synchronously one after the other, but are added to an asynchronous queue and then finally executed together, i.e., batch processing. React’s data manipulation is clearer than vUE’s two-way binding.
Conclusion: Each company has its own choice as to whether to use VUE or React. No matter which one is born to improve our work efficiency, each one has its own advantages and disadvantages, which will not be elaborated here. I have used Vue and React. Most of vue’s community is run by the author You Yuxi or his team. The surrounding methods are officially recommended and a series of apis are provided. The React JS library was created by Facebook and has a large number of contributors as well as a large community of developers who contribute their solutions to various problems. The community is quite active and flexible.
2. umi
:React
A one-stop build tool
This is a one-stop build tool right out of the box that includes the tools necessary for our development process, we just need to care about the business, and it takes care of the rest. Webpack + webpack-dev-server + Babel + postcss +… The react-router router is used for routing.
👆 This is how it was used in the previous generation. Tools are tools and libraries are libraries. More recently, we’ve found that tools and libraries can be mixed together, and tools are part of the framework. Reduce the amount of code developers need to write by facilitating development through conventions, automatic generation and parsing of code. Interfaces are the New Frameworks.
Umi website
Umi document
3.Mobx
or Redux
?
Mobx is a powerful, easy-to-use state management tool. Even the authors of Redux have recommended it, and in many cases you can use Mobx instead of Redux.
Add in the...Copy the code
Redux is a JavaScript state container that provides predictable state management
Add in the...Copy the code
Mobx official documentation redux
4. Egg.js
Egg.js is an enterprise application framework of Ali based on NODEJS and KOA2, based on ES6, ES7 and NodeJS. For a beginner’s guide to Node, see here
Add in the...Copy the code
An Egg. Js’s official website
An Egg. Js document
React + Typescript
Ts is js in strict mode, so to speak, and the more code we write, the more we understand how important rules are. Ts is under the condition of without changing the original js written on it to add static type checking, we don’t have to worry about taking over the project document, no comment, now have a ts, type system in fact is the best document, direct and clear labelling: what is required, which is optional, as well as the specific data type is clear.
React cooperated with the practice of TS, so it was really necessary to write. It not only strictly required ourselves, but also unified our writing habits, so that the overall code would be very clear whether we read the code by ourselves or entrusted to other students for maintenance.
Typescript practices and React with typescript practices
6. Use the right Ant Design Pro tool to double the efficiency
Ant Design Pro is based on Ant Design and UMI’s packaging of a set of enterprise-level back-end front-end/Design solutions, committed to the Design specifications and basic components, continue to build up, extract typical templates/business components/supporting Design resources. To further improve the experience of “users” and “designers” in the design and development process of enterprise-level background products.
Ant Design Pro strives to provide an out-of-the-box development experience by providing a complete scaffolding for internationalization, permissions, mocks, data flows, network requests, and more. Best practices are provided to reduce learning and development costs for these common scenarios in the middle and back end.
At the same time, in order to provide more efficient development experience, provides a series of template components, ProLayout, ProTable, ProList are a good helper in the development of background, can significantly reduce the sample code.
You can see the entire Ant Design Pro architecture in the larger image at 👇 below.
Ant Design Pro website
Ant Design Pro documentation
7. A library of productivity toolsahooks
Ahooks is a React Hooks library dedicated to providing frequent, high-quality Hooks. The React function is a library that contains some of the most common functions and methods, as well as methods that are reacted on the react function to make it more relevant to the needs of the business
Introduction and use are also extremely concise:
import React from "react";
import { useToggle } from "ahooks";
export default () => {
const [ state, { toggle } ] = useToggle();
return (
<div>
<p>Current Boolean: {String(state)}</p>
<p>
<button onClick={() => toggle()}>Toggle</button>
</p>
</div>
);
};
Copy the code
About ahooks official website
8. React
çš„ Hooks
Compared to the componentClass
What are the advantages and disadvantages of class components
Class component, an HTML component returned by Render. Class components have not only State, but also a life cycle. Each instance of a component, from creation, to execution, to destruction, emits a series of events called component lifecycle functions.
Here are the class class components
import { PureComponent } from "react"; class Parent extends PureComponent { constructor(props) { super(props); this.state = { id: 1 }; } render() {return (<div>); } } export default Parent;Copy the code
Hook is a new feature in React 16.8. It lets you use state and other React features without having to write a class. Not only is it simple to write, but you don’t have to worry about this anymore.
The following ishooks
Function component
import React from 'react'; import { Button } from 'antd'; Const App = () => {const handleClick = () => {console.log(' button click '); }; <Button onClick={handleClick}> Button </Button>; }; export default App;Copy the code
On the difference between the two:
- It’s written as the largest,
Hooks
It’s much cleaner, it just returns a function body;class
The component requires a constructorconstructor
And the needrender
return
ahtml
Body. - The second is about
this
Point to the problem inclass
Within the component, we use state and add events with this in mindhooks
There are no such considerations at all. - And then there’s the classification of the life cycle in
clas
We can get a lot of life cycles,Look here, we can do corresponding operations in different stages, inhooks
By incorporating most of the life cycle, we can almostuseEffect
Do most of the operations in.
As we get more used to using hooks, go back to the class component and see that classes are bloated, like one in summer and one in winter, and we can do the same thing in a much more elegant way with less code, so why not?
Here is the official advice on whether the two methods should be unified
9. Select and use according to the scenariouseState
oruseReducer
We all know that useState and useReducer can be used to store state, so what is the difference? Look here
10. setState
Is it synchronous or asynchronous? whensetState
When the same reference is returned,render
Will it be implemented?
SetState is executed asynchronously. We all know that react doesn’t allow you to change the value of state directly. We need to use setState to change data, and it doesn’t take effect immediately. It’s asynchronous. So don’t assume you can get the latest value immediately after calling setState. Sequential setStates are not executed synchronously one after the other, but are added to an asynchronous queue and then finally executed together, i.e., batch processing.
Render does not execute when setState returns the same reference, as in the following example:
import { PureComponent } from "react"; import { Button } from "antd"; class Workplace extends PureComponent { constructor(props) { super(props); this.state = { a: 1 }; } action = {handleParams: () => {// When 'setState 'performs the same assignment as the initial value: this.setState({a: 1}) console.log('setState performed ')}}; Render () {return (<div> <h1> worktable </h1> <Button onClick={this.action.handleParams}> {console.log('render executed ')} </div>); } } export default Workplace;Copy the code
First render is executed, which is a must, then we click the button, execute setState, and look at the console output, there is no second render:
Now I will change this. When the button is clicked, I will change the value of a to 3 and leave the rest unchanged as above:
HandleParams: () => {this.setState({a: 3}) console.log('setState executed ')}Copy the code
Now look at the result returned from the console:
Compared to the last operation, this time returns a render print, that is, when setState returns the same reference, the render will not be triggered. The react diff algorithm determines that when two values are the same, the render will not continue down.
About diff algorithm:
React Diff compares old and new nodes layer by layer from the Root node of the Fiber tree. The component’s key and type determine whether the old node needs to be reused. The node’s index ultimately determines whether the DOM needs to be moved. Nodes that are not being reused are removed, so there is no need for diff of the subtree, and therefore no need for cross-level diff.
Compare different types of elements:
When the root node has a different type of element, React disassembles the existing tree and creates a new one. For example, when an element changes from to , from
to
, or from
Compare elements of the same type:
When comparing two React elements of the same type, React preserves the DOM node and only compares and updates the changed attributes.
<div className="before" title="stuff" />
<div className="after" title="stuff" />
Copy the code
By comparing the two elements, React knows that it only needs to change the className attribute on the DOM element.
Recurse on child nodes:
By default, React iterates through lists of both child elements at the same time when recursing to the child elements of a DOM node
<ul>
<li>first</li>
<li>second</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
Copy the code
React matches two
trees, then matches the second< li>second tree, and finally inserts the
tree of the third element.
Recommended articles:
Diff algorithm (Mom doesn’t worry about my Diff interviews anymore)
React diff
Of course, if you really need to get the assigned value, you can use setTimout to get it, as follows:
ChangeText () {setTimeout(() => {this.setState({message: "I am a new message"}); console.log(this.state.message); // I am new message}, 0); }Copy the code
11. useCallback
,useMemo
,useEffect
The difference between?
Common: Both update only when a dependency changes;
The difference is that useMemo is a cache variable, useCallback is a cache callback function, and useEffect is delayed until the browser finishes rendering the screen, regardless of whether the parameter is monitored, and is updated when the dependency changes.
The listening process for each method?
Both use the second argument of the function to do dependency collection and then listen for changes to the second argument to determine whether to re-render. Whenever a change occurs, get the latest value, update the function/variable in the cache, etc. Here’s an example of useMemo:
Before using useMemo:
import React, { useState } from 'react'; const App = () => { const [count, setCount] = useState(0); const userInfo = { name: "Jace", age: count }; Return <div> name: {userinfo.name}</div>} export default AppCopy the code
Using useMemo:
import React, { useState, useMemo } from 'react'; const App = () => { const [count, setCount] = useState(0); const userInfo = useMemo(() => { return { name: "Jace", age: count }; }, [count]); Return <div> name: {userinfo.name}</div>} export default AppCopy the code
Obviously the above userInfo will be a new object each time and will cause the component to re-render whether the count changes or not, whereas the lower one will return the new object only after the count changes.
useEffect
thereturn
When will it be implemented?
UseEffect returns a function that executes something when a component is destroyed, so that the contents of the return function are executed when the component is destroyed:
useEffect(() => { handelColumns(tabVal || 'intention'); // it needs to be a function. Return () => {// Console.log (1) will only be executed on destruction; }; } []);Copy the code
So when we use it, we can choose the right one according to its function.
12. Higher-order functions
HOC is an advanced technique used in React to reuse component logic. HOC itself is not part of the React API; it is a design pattern based on the composite features of React. Higher-order functions are used to strengthen components, reuse logic, improve rendering performance, etc.
As for higher-order functions, my understanding is not profound, and I will share it with you when MY wings are rich. I recommend reading this article
13. The customhooks
A custom Hook is a function whose name starts with “use” that can call other hooks from within. Here is an example of the custom hooks shared earlier
14. What data changes trigger rerendering?
Normal rendering of components is a must, but when unnecessary rendering occurs, it can be costly to performance on the one hand, and can cause the user to feel like the page is stuck on the other. So what data changes trigger rendering?
- Component state
state
The value of is changed, which is triggeredsetState
Method, which triggers rendering by default. Of course, there are special cases: whensetState
Does not fire when the same reference is returnedrender
; - The father of the component
props
After being modified, all child components are also re-rendered by default; - Of the child component
state
State changes do not affect the parent, and the parent does not re-render;
15. Performance optimization, how to avoid unnecessary rendering?
In React, we learned that when you update a component, it triggers all the child components to update. The entire component tree is rerendered in turn, which means that every change in the APP causes the entire APP to be rerendered. Even though React doesn’t actually change the DOM, it evaluates the VDOM and makes comparisons. That’s a lot of work, and you’ll see the entire UI slow down, especially in a large application. This is one reason why the React component requires immutability. In our actual development process, we need to determine whether to load on demand according to different scenarios. The following is a look respectively, and then we can choose according to their own needs:
React.lazy
It is not loaded the first time, and then loaded when the dependency is modified
The react. lazy function allows you to render dynamically imported components in the same way as regular components. React.lazy is used for not loading the file for the first time and then loading it when there is an update. For details, see here
React.Memo
The first load, there are changes will be updated, otherwise do not re-render
If your component is rendering the same props, you can improve the performance of the component by wrapping it in a react.Memo call to remember the component’s rendering results. This means that in this case React will skip the render component and simply reuse the results of the last render. React.memo only checks the props changes. If the function component is wrapped in react. Memo and its implementation has useState, useReducer, or useContext hooks, it will still re-render when state or context changes. For details, see here
shouldComponentUpdate
Check whether the output of the React component is affected by changes to the current state or props based on the return value of shouldComponentUpdate(). ShouldComponentUpdate () is called before rendering when props or state changes. The default return value is true. Do not attempt to rely on this method to “block” rendering, as this can be buggy. In most cases, you can inherit react.pureComponent instead of shouldComponentUpdate(). It overrides the implementation of shouldComponentUpdate() with a shallow comparison of the current and previous props and state.
ShouldComponentUpdate (nextProps, nextState) {// Render return true; }Copy the code
React.PureComponent
Like React.Memo, the PureComponent makes a shallow comparison between props and state and reduces the possibility of skipping necessary updates. , but react. PureComponent applies to class components, not function components.
React.componentwe all know that react.componentis the base class that defines the React component using ES6 classes:
class Greeting extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; }}Copy the code
React.PureComponent is very similar to react.component.react.component.react.pureComponent. The difference is that shouldComponentUpdate() is not implemented in react.pureComponent, which is implemented in a shallow way to compare prop and state. If the object contains complex data structures, it is possible to produce incorrect alignment results because deep differences cannot be examined. Here is an example of a PureComponent:
The parent component:
import React, { PureComponent } from "react"; import { Button } from "antd"; import Child from "./child"; class Analysis extends PureComponent { constructor(props) { super(props); this.state = { b: 1 }; } action = { handleParams: () => { this.setState({b:2}) } }; Render () {return (<div> <h1> <Button onClick={this.action.handleparams}>handleParams</Button> {the console. The log (' parent component rendering ')} < div > Child components: < Child / > < / div > < / div >). } } export default Analysis;Copy the code
Child components:
import { PureComponent } from "react"; class Child extends PureComponent { constructor(props) { super(props); } to render () {return (< div > < h1 > child - page < / h1 > {the console. The log (' child components to render ')} < / div >). } } export default Child;Copy the code
When we update the props of the parent component, the console does not output a rendering of the child component because the child component is not using the props of the parent component, thus reducing unnecessary rendering.
This article is not over yet, I hope I can continue to update, if you are reading this article any questions 🤔, feel free to leave a comment.
If the pro feel my article is good, you can add attention to oh!
Content is still in the continuous update, afraid of missing the update of a focus on bai! Point a concern not to get lost oh! 😄
Please push
Note: If you have a partner company looking for a job, please contact me! React, TS, ANTD, Webpack… Please refer to my article. Location: Beijing, Tel: 15210667658