React benefits over native
- React is implemented most thoroughly, even to functional level atomic components. A high degree of componentization makes our components easy to maintain, combine and expand.
- Natural layering The code in JQuery era is mostly noodle code with serious coupling. Modern frameworks, whether MVC, MVP or MVVM patterns, can help us layering. Code decoupling is easier to read and write.
- Ecology Now mainstream frameworks have their own ecology, whether it’s data flow management architecture or UI libraries, there are mature solutions.
- Modern front-end frameworks automatically update the DOM by default, instead of requiring manual operation, which liberates the developer’s manual DOM cost, indirectly improves the development efficiency, and fundamentally solves the problem of UI and state synchronization.
React vs. Vue
-
The same
- Virtual DOM – Maps real DOM to better track rendered pages through diff comparisons between old and new DOM.
- Componentization – Breaking an application into functional modules that can be connected to each other in appropriate ways.
- Build tools – Each has its own build tools and uses Webpack + Babel to build scaffolding tools.
- Chrome Developer tools – both have great Chrome extensions to help find bugs
- Vue includes vue-Router and Vuex, React includes react-Router and react-redux
-
different
- Module VS JSX – Vue recommends writing a template that approximates regular HTML for rendering, while React recommends writing JSX.
- Listen for data changes differently — Vue uses mutable data, while React emphasizes immutable data. In Vue, the data bound by v-model will change the corresponding value after the user changes the input value. React is a change that needs to be set with setState
- Diff is different — Vue uses a bidirectional linked list to update the DOM while comparing, while React uses a Diff queue to store the DOM that needs to be updated to create a patch tree and update the DOM in a unified batch
- The development team — Vue started with Evan You as the core, and later recruited others to form the team; React was built by the Facebook team from the beginning. Vue is easier to understand than React.
setState
- What happens after setState is called?
- After calling setState in your code, React merges the passed parameter object with the current state of the component, triggering a process called reconciliation
- After the reconciliation process, React builds the React element tree based on the new state in a relatively efficient way and starts rerendering the entire UI
- After React gets the element tree, React automatically calculates the node differences between the new tree and the old tree and minimizes and re-renders the interface based on the differences
In Diff, React is able to know with relative precision what has changed and how, ensuring that updates are made on demand rather than completely rerender
- Merge parameter objects, triggering the harmonization process
- Calculate the difference between old and new trees (Diff)
- Minimize and re-render according to the differences
SetState is synchronous
- Sometimes synchronous, sometimes asynchronous
- SetState is asynchronous in synthesized events and hook functions, and asynchronous in native events and setTimeout.
- The asynchrony of setState does not mean that it is internally realized by asynchronous code. The process itself is synchronous with the code, but the call order of the synthesized event and hook function and hook function is before the update, so that the updated value cannot be immediately obtained in the synthesized event and hook function, thus forming the so-called asynchrony.
- SetState takes the second argument to retrieve the updated result in the callback method
The React this problem
import React, { Component } from 'react'
class App extends Component {
constructor (props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick () {
console.log('jsliang 2020');
}
handleClick2 = () = > {
console.log('jsliang 2021');
}
render () {
// There are four binding methods
return (
<div className='App'>{/* Bind from constructor */}<button onClick={this.handleClick}>btn 1</button>{/* bind this */}<button onClick={this.handleClick.bind(this)}>btn 2</button>{/* Method 3: return event via arrow function */}<button onClick={()= > this.handleClick()}>btn 3</button>{/* method 4: turn method into arrow function */}<button onClick={this.handleClick2}>btn 4</button>} {this.handleclick ()} {this.handleclick ()}</div>)}}export default App;
Copy the code
- What’s the difference between using the bind and arrow functions
- The arrow function, apart from the lack of code, differs from normal functions in that this is defined when the function is declared, and is usually implicitly defined as the scope this when the function is declared.
- Foo. Prototype. a = function() {} by a pointer to the prototype chain
Redux workflow
- The core concepts of Redux:
- Store: A place to Store data. Think of it as a container and only have one Store for the entire application
- State: The Store object contains all data. If you want the data at a point in time, you need to create a snapshot of the Store
- Action: State changes, resulting in View changes. However, the user does not touch Stae, only View. Therefore, the change in State must be caused by the View. An Action is a notification from the View that the State should change.
- Action Creator: The View will have as many actions as it wants to send. It would be cumbersome to write them all by hand, so let’s define a function to generate the Action
- Reducer: After the Store receives the Action, a new State must be given so that the View will change. This State calculation process is called Reducer. Reducer is a function that takes Action and the current State as parameters and returns a new State.
- Dispatch: is the only way for a View to issue an Action
- Completed workflow
- First, the user issues an Action (via the View) using the Dispatch method
- The Store automatically calls the Reducer with two parameters: the current State and the received Action. The Reducer returns the new State
- Whenever the State changes, the Store calls a listener function to update the View
How does React – Redux work?
- Provider: Providers encapsulate the entire application from the outside and pass the Store to the Connect module
- Connect: Connects React and Redux
- GetState: connect uses context to get stores in the Provider, and uses store.getstate () to get all states in the entire store tree
- Package original components: Pass state and action inside the original component as props. WrapWithConnect returns a ReactComponent object, Connect, that rerenders the original WrappedComponent passed in externally, And to Connect the incoming mapStateToProps mapDispatchToProps and components on the original props after the merger, passed to WrappedComponent properties
- Listen for Store Tree changes: Connect caches the state of the store Tree and compares the current state with the state before the change to determine whether to call this.setState() to trigger a re-rendering of connect and its children
Virtual DOM
Browser rendering process
- Create a DOM tree. Parsing HTML elements with an HTML parser creates a DOM tree
- Create a CSS rule tree. The CSS file and inline styles are parsed with a CSS parser to generate a style sheet for the page
- Create the Render tree. Construct the Render tree by associating the DOM tree with the CSS rule tree
- The Layout of the Layout. Based on the Render tree, the browser begins the layout by determining a precise coordinate for each node in the Render tree to appear on the display
- Draw the Painting. Based on the Render tree and node display coordinates, call the paint method for each node to draw them
DOM manipulation is expensive
Because DOM manipulation in a browser is expensive
- When manipulating the DOM with native JS or JQuery, the browser executes the process from beginning to end, starting with building the DOM tree
Key points to expand: Reflux and redraw
Frequent DOM operations will cause certain performance problems, so we need to abstract at this layer and update the differences to the DOM as much as possible at one time during the patch process to ensure that the DOM will not suffer from poor performance.
But that doesn’t solve the problem, so here comes the virtual DOM;
The virtual DOM is essentially an abstraction of the real DOM by describing a DOM node with a native JavaScript object
Real DOM node
<div id="container">
<ul>
<li></li>
</ul>
</div>
Copy the code
JS emulates the virtual DOM
const tree = Element('div', { id: 'container' }, {
Element('ul', {}, [
Element('li', {},'New node value']])});const root = tree.render();
document.querySelector('#container').appendChild(root);
Copy the code
You can see the three most basic properties of a virtual DOM object
- The tag type
- Attribute of the tag element
- Child node of the tag element
The Diff algorithm
The time complexity of the complete comparison between the two trees is 0(n^3), while the time complexity of the React Diff algorithm is 0(n).
To achieve such a low time complexity means that only nodes at the same level will be compared when comparing differences, because the actual complexity of the algorithm will be too high if the complete comparison is carried out, so the complete comparison method is abandoned and the same-level comparison method is adopted
The core of Diff algorithm is to carry out depth-first traversal of virtual DOM nodes, number each virtual node, compare nodes of the same level in the traversal process, and finally get the difference after comparison
The roughest way to implement Diff is to walk through each new virtual DOM node and compare it to the old one. If it exists in the old DOM, uninstall it and change it to a new one
React/Vue key: When writing a service, we are often told that the key value cannot be index, why?
If we have four elements, the old ones are 1, 2, 3, 4, and the new ones are 1, 3, 2, 4, then if we use index, they will always be 0-3. React or Vue won’t be able to listen for a change as well
So generally, we position the key value as the id of the array or some other value, so that we can better monitor it when it changes
This way, after the Diff comparison is complete, we can retrieve the content that needs to be changed and finally update the actual DOM node
Virtual DOM implementation principle
- The virtual DOM is essentially a JavaScript object, an abstraction of the real DOM
- When the state changes, record the difference between the new tree and the old tree
- Finally, the differences are updated into the real DOM
Compare the virtual DOM with the real DOM
- advantages
- Ensure the lower limit of performance: Virtual DOM can find the minimum difference through Diff, and then batch patch. Although this operation is not as good as manual optimization, the performance is much better than rough DOM operation, so virtual DOM can ensure the lower limit of performance
- No manual MANIPULATION of the DOM: Diff and patch of the virtual DOM are done automatically in a single update, so we don’t need to manually manipulate the DOM, which greatly improves development efficiency
- Cross-platform: The virtual DOM is essentially a JavaScript object, and DOM is highly platform dependent. In contrast, the virtual DOM can be more easily cross-platform, such as server rendering, mobile development, etc
- disadvantages
-
Extreme optimization is not possible: in some applications with high performance requirements, virtual DOM cannot be optimized specifically and carefully. For example, vsCode directly manually operates the DOM to perform extreme performance optimization.
-
The Diff algorithm
Compare the difference between the native virtual DOM and the new virtual DOM, using Diff(Different) algorithm
In React, for setState, it operates asynchronously, changing the data in state uniformly
- Compare the DOM nodes of the first layer. If they are the same, continue to compare them down. If it is different, stop the comparison and update the DOM nodes at the first level and below
- Compare the second DOM node……
- Form a comparison algorithm
conclusion
- Break down the tree structure by hierarchy, comparing only peer elements
- Add a unique key attribute to each unit of the list structure for easy comparison
- React will only match components of the same class.
- Merge operation. When calling component’s setState method, React marks it as dirty. At the end of each event loop, React checks that all components marked dirty are redrawn
- Select subtree rendering. Developers can rewrite shouldComponentUpdate to improve Diff performance